commoncompute 0.2.0__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.
- {commoncompute-0.2.0 → commoncompute-0.3.0}/PKG-INFO +89 -69
- {commoncompute-0.2.0 → commoncompute-0.3.0}/README.md +88 -68
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/__init__.py +7 -14
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/_config.py +3 -2
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/_transport.py +2 -2
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/cli.py +21 -12
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/connect.py +2 -1
- {commoncompute-0.2.0 → commoncompute-0.3.0}/pyproject.toml +5 -1
- {commoncompute-0.2.0 → commoncompute-0.3.0}/.gitignore +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/LICENSE +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/_async_client.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/_async_tasks.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/_generated_workloads.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/aws_batch.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/client.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/compat/__init__.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/compat/openai.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/errors.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/models.py +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/py.typed +0 -0
- {commoncompute-0.2.0 → commoncompute-0.3.0}/commoncompute/tasks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commoncompute
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Official Python SDK for Common Compute — the batch AI bill you shouldn't be paying.
|
|
5
5
|
Project-URL: Homepage, https://commoncompute.ai
|
|
6
6
|
Project-URL: Documentation, https://commoncompute.ai/docs
|
|
@@ -44,11 +44,14 @@ for **successful** jobs — each with a verifiable receipt.
|
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
pip install commoncompute # core: httpx + pydantic only
|
|
47
|
-
pip install "commoncompute[cli]" # + the `
|
|
48
|
-
|
|
47
|
+
pip install "commoncompute[cli]" # + the `commoncompute` command line
|
|
48
|
+
commoncompute login # opens the browser — no key to copy-paste
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
The command is `commoncompute`. A short `cc` is **not** installed — that name
|
|
52
|
+
belongs to the system C compiler. Want the shorthand? `alias cc="commoncompute"`.
|
|
53
|
+
|
|
54
|
+
`commoncompute login` (or `commoncompute.connect()` from a script or notebook) opens an
|
|
52
55
|
approval page in your browser; click **Approve** and a fresh API key is saved
|
|
53
56
|
to `~/.config/commoncompute/credentials`, where the SDK finds it automatically.
|
|
54
57
|
Prefer explicit config? `export CC_API_KEY=cc_live_...` works everywhere and
|
|
@@ -61,7 +64,8 @@ import commoncompute as cc
|
|
|
61
64
|
|
|
62
65
|
client = cc.Client() # reads CC_API_KEY, or the saved credentials file
|
|
63
66
|
|
|
64
|
-
job = client.
|
|
67
|
+
job = client.submit("coreml_embed", {"input": ["what is the neural engine?"]},
|
|
68
|
+
model_id="bge-base")
|
|
65
69
|
print(job.job_id, job.locked_price_usd, job.eta_seconds) # price known BEFORE it runs
|
|
66
70
|
|
|
67
71
|
result = client.result(job) # waits, downloads, attaches the receipt
|
|
@@ -69,7 +73,10 @@ print(result.output)
|
|
|
69
73
|
print(result.receipt) # signed proof of what ran, where, for how much
|
|
70
74
|
```
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
Prefer the OpenAI-style surface? `client.embeddings.create(input=[...],
|
|
77
|
+
model="bge-base")` returns vectors synchronously.
|
|
78
|
+
|
|
79
|
+
## Examples — live today
|
|
73
80
|
|
|
74
81
|
### 1. OCR / document extraction — vs AWS Textract
|
|
75
82
|
|
|
@@ -78,38 +85,40 @@ job = client.ocr.extract("https://example.com/contracts.pdf", structured=True)
|
|
|
78
85
|
result = client.result(job) # blocks + bounding boxes as JSON
|
|
79
86
|
```
|
|
80
87
|
|
|
81
|
-
### 2.
|
|
88
|
+
### 2. Embeddings in bulk
|
|
82
89
|
|
|
83
90
|
```python
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
for result in client.submit_many(
|
|
92
|
+
"coreml_embed",
|
|
93
|
+
[{"input": chunked(doc)} for doc in corpus],
|
|
87
94
|
max_concurrent=16,
|
|
88
|
-
)
|
|
95
|
+
):
|
|
96
|
+
save(result.output) # results stream as they complete
|
|
89
97
|
```
|
|
90
98
|
|
|
91
|
-
### 3.
|
|
99
|
+
### 3. Background removal
|
|
92
100
|
|
|
93
101
|
```python
|
|
94
|
-
job = client.
|
|
95
|
-
top = client.result(job).output
|
|
102
|
+
job = client.images.remove_background("product-shot.png")
|
|
96
103
|
```
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
Also live: speech synthesis, image classification/detection/pose, barcode
|
|
106
|
+
reading, HEIC conversion — plus the generic `client.submit(workload_id,
|
|
107
|
+
payload)` for anything marked **live** in
|
|
108
|
+
[the catalog](https://commoncompute.ai/workloads).
|
|
99
109
|
|
|
100
|
-
|
|
101
|
-
job = client.translate(catalog_descriptions, target_lang="de")
|
|
102
|
-
```
|
|
110
|
+
### In preview
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
`client.translate(...)` and `client.video.transcode(...)` run on preview
|
|
113
|
+
capacity — functional, not yet GA.
|
|
105
114
|
|
|
106
|
-
|
|
107
|
-
job = client.images.remove_background("product-shot.png")
|
|
108
|
-
```
|
|
115
|
+
### Not live yet
|
|
109
116
|
|
|
110
|
-
|
|
111
|
-
`client.
|
|
112
|
-
|
|
117
|
+
`client.transcription.*`, `client.rerank(...)`, `client.images.generate(...)`,
|
|
118
|
+
`client.chat.*`, and `client.build.ios_test(...)` target workloads still
|
|
119
|
+
marked *coming soon*: the API refuses them with a clear
|
|
120
|
+
`workload_not_available` error (HTTP 409) rather than queueing a job that
|
|
121
|
+
won't run. They activate automatically as those lanes go live — watch
|
|
113
122
|
[the catalog](https://commoncompute.ai/workloads).
|
|
114
123
|
|
|
115
124
|
## Price before execution, hard caps, dry runs
|
|
@@ -183,48 +192,59 @@ raw request/response dicts instead of typed `Job`/`TaskResult` objects.
|
|
|
183
192
|
|
|
184
193
|
## CLI
|
|
185
194
|
|
|
186
|
-
`pip install "commoncompute[cli]"` installs the `
|
|
195
|
+
`pip install "commoncompute[cli]"` installs the `commoncompute` command.
|
|
196
|
+
|
|
197
|
+
> **Why not a short `cc`?** Because `cc` is the Unix C compiler
|
|
198
|
+
> (`/usr/bin/cc`). Shipping a binary by that name puts it ahead of the real
|
|
199
|
+
> compiler on `PATH` for anyone whose Python bin directory sorts first, and
|
|
200
|
+
> every build that shells out to `cc` then fails with a CLI usage error
|
|
201
|
+
> instead of compiling. So `commoncompute` is the only command installed. If
|
|
202
|
+
> you want the shorthand, opt in yourself:
|
|
203
|
+
>
|
|
204
|
+
> ```bash
|
|
205
|
+
> alias cc="commoncompute" # add to ~/.zshrc or ~/.bashrc
|
|
206
|
+
> ```
|
|
187
207
|
|
|
188
208
|
```bash
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
209
|
+
commoncompute login # stores the key locally
|
|
210
|
+
commoncompute quote vision_ocr --units 5 # price + ETA, no execution
|
|
211
|
+
commoncompute submit coreml_embed --payload '{"input":["hi"]}' --wait
|
|
212
|
+
commoncompute jobs list
|
|
213
|
+
commoncompute jobs get <id>
|
|
214
|
+
commoncompute balance
|
|
215
|
+
commoncompute receipts export --format csv --out receipts.csv
|
|
196
216
|
```
|
|
197
217
|
|
|
198
218
|
### Commands
|
|
199
219
|
|
|
200
220
|
| Command | What it does |
|
|
201
221
|
|---------|--------------|
|
|
202
|
-
| `
|
|
203
|
-
| `
|
|
204
|
-
| `
|
|
205
|
-
| `
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
|
|
227
|
-
`
|
|
222
|
+
| `commoncompute login` / `commoncompute logout` | Store / remove the API key (browser approval, or `--api-key`) |
|
|
223
|
+
| `commoncompute whoami` | Show the account behind the current key |
|
|
224
|
+
| `commoncompute balance` | Current workspace balance |
|
|
225
|
+
| `commoncompute usage` | Spend + call-count rollups over a date range (`--start`, `--end`, `--group-by`) |
|
|
226
|
+
| `commoncompute spend` | Total spend over the last `--days` N, grouped by workload |
|
|
227
|
+
| `commoncompute tier` | Current volume tier and the next threshold |
|
|
228
|
+
| `commoncompute workloads` | List available workloads |
|
|
229
|
+
| `commoncompute models` | List models (`--workload` to filter) |
|
|
230
|
+
| `commoncompute quote` | Price + ETA for a workload without submitting (`--units`, `--priority`, `--model`) |
|
|
231
|
+
| `commoncompute submit` | Submit one job (`--payload/-f`, `--model`, `--priority`, `--wait`, `--timeout`) |
|
|
232
|
+
| `commoncompute submit-many` | Submit a JSONL file of payloads; stream one result per line as NDJSON (`--input/-i`, `--max-concurrent`, `--no-wait`) |
|
|
233
|
+
| `commoncompute chat` | One-shot chat message to a model (`--model`, `--stream/--no-stream`) |
|
|
234
|
+
| `commoncompute embed` | Embed a single string (prints the vector length) |
|
|
235
|
+
| `commoncompute playground` | Open the web playground |
|
|
236
|
+
| `commoncompute jobs list` | Recent submissions, newest first (`--limit/-n`) |
|
|
237
|
+
| `commoncompute jobs get <id>` | Fetch one job |
|
|
238
|
+
| `commoncompute jobs wait <id>` | Poll a job to a terminal state (`--timeout/-t`) |
|
|
239
|
+
| `commoncompute jobs events <id>` | Event timeline for a job |
|
|
240
|
+
| `commoncompute jobs download <id>` | Download a job's result (`--out/-o`, else stdout) |
|
|
241
|
+
| `commoncompute keys list` / `create` / `revoke` | Manage API keys |
|
|
242
|
+
| `commoncompute receipts list` | Receipts for completed jobs (`--limit/-n`) |
|
|
243
|
+
| `commoncompute receipts get <id>` | Signed receipt for a single job |
|
|
244
|
+
| `commoncompute receipts export` | Export receipts as CSV or JSON (`--format/-f`, `--out/-o`, `--limit/-n`) |
|
|
245
|
+
| `commoncompute config path` / `show` / `set` / `unset` | Inspect and edit local settings (see below) |
|
|
246
|
+
|
|
247
|
+
`commoncompute --version` (or `-V`) prints the version. Every read command that renders a
|
|
228
248
|
table also accepts **`--json`** for plain, ANSI-free machine-readable output —
|
|
229
249
|
`whoami`, `balance`, `usage`, `spend`, `tier`, `workloads`, `models`, `quote`,
|
|
230
250
|
`submit`, `jobs list/get/wait/events`, `keys list`, and `receipts list`.
|
|
@@ -234,20 +254,20 @@ table also accepts **`--json`** for plain, ANSI-free machine-readable output —
|
|
|
234
254
|
Typer ships completion for bash, zsh, fish, and PowerShell:
|
|
235
255
|
|
|
236
256
|
```bash
|
|
237
|
-
|
|
238
|
-
|
|
257
|
+
commoncompute --install-completion # install for the current shell
|
|
258
|
+
commoncompute --show-completion # print the script to inspect or customise
|
|
239
259
|
```
|
|
240
260
|
|
|
241
261
|
### Exit codes
|
|
242
262
|
|
|
243
|
-
Scripts can branch on `
|
|
263
|
+
Scripts can branch on `commoncompute`'s exit status:
|
|
244
264
|
|
|
245
265
|
| Code | Meaning |
|
|
246
266
|
|------|---------|
|
|
247
267
|
| `0` | Success |
|
|
248
268
|
| `1` | API or runtime error (network, server, bad request) |
|
|
249
269
|
| `2` | Usage error — missing/invalid arguments, or no credentials found |
|
|
250
|
-
| `3` | The job reached a **failed** terminal state (`failed` / `dead_letter` / `cancelled`) — `
|
|
270
|
+
| `3` | The job reached a **failed** terminal state (`failed` / `dead_letter` / `cancelled`) — `commoncompute jobs wait` and `commoncompute submit --wait` only |
|
|
251
271
|
|
|
252
272
|
## Migrating from OpenAI (optional)
|
|
253
273
|
|
|
@@ -316,14 +336,14 @@ Environment variables take precedence over both files at runtime:
|
|
|
316
336
|
Inspect and edit the local config from the CLI:
|
|
317
337
|
|
|
318
338
|
```bash
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
339
|
+
commoncompute config path # print the config directory
|
|
340
|
+
commoncompute config show # settings + active credential source (key masked)
|
|
341
|
+
commoncompute config set base_url https://api.commoncompute.ai
|
|
342
|
+
commoncompute config set org my-workspace
|
|
343
|
+
commoncompute config unset org
|
|
324
344
|
```
|
|
325
345
|
|
|
326
|
-
Env vars still win at runtime — `
|
|
346
|
+
Env vars still win at runtime — `commoncompute config set` writes the file, but
|
|
327
347
|
`CC_BASE_URL` / `CC_ORG` override it for a given process.
|
|
328
348
|
|
|
329
349
|
Python 3.9+. Core dependencies: `httpx`, `pydantic`. MIT license.
|
|
@@ -9,11 +9,14 @@ for **successful** jobs — each with a verifiable receipt.
|
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
pip install commoncompute # core: httpx + pydantic only
|
|
12
|
-
pip install "commoncompute[cli]" # + the `
|
|
13
|
-
|
|
12
|
+
pip install "commoncompute[cli]" # + the `commoncompute` command line
|
|
13
|
+
commoncompute login # opens the browser — no key to copy-paste
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
The command is `commoncompute`. A short `cc` is **not** installed — that name
|
|
17
|
+
belongs to the system C compiler. Want the shorthand? `alias cc="commoncompute"`.
|
|
18
|
+
|
|
19
|
+
`commoncompute login` (or `commoncompute.connect()` from a script or notebook) opens an
|
|
17
20
|
approval page in your browser; click **Approve** and a fresh API key is saved
|
|
18
21
|
to `~/.config/commoncompute/credentials`, where the SDK finds it automatically.
|
|
19
22
|
Prefer explicit config? `export CC_API_KEY=cc_live_...` works everywhere and
|
|
@@ -26,7 +29,8 @@ import commoncompute as cc
|
|
|
26
29
|
|
|
27
30
|
client = cc.Client() # reads CC_API_KEY, or the saved credentials file
|
|
28
31
|
|
|
29
|
-
job = client.
|
|
32
|
+
job = client.submit("coreml_embed", {"input": ["what is the neural engine?"]},
|
|
33
|
+
model_id="bge-base")
|
|
30
34
|
print(job.job_id, job.locked_price_usd, job.eta_seconds) # price known BEFORE it runs
|
|
31
35
|
|
|
32
36
|
result = client.result(job) # waits, downloads, attaches the receipt
|
|
@@ -34,7 +38,10 @@ print(result.output)
|
|
|
34
38
|
print(result.receipt) # signed proof of what ran, where, for how much
|
|
35
39
|
```
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
Prefer the OpenAI-style surface? `client.embeddings.create(input=[...],
|
|
42
|
+
model="bge-base")` returns vectors synchronously.
|
|
43
|
+
|
|
44
|
+
## Examples — live today
|
|
38
45
|
|
|
39
46
|
### 1. OCR / document extraction — vs AWS Textract
|
|
40
47
|
|
|
@@ -43,38 +50,40 @@ job = client.ocr.extract("https://example.com/contracts.pdf", structured=True)
|
|
|
43
50
|
result = client.result(job) # blocks + bounding boxes as JSON
|
|
44
51
|
```
|
|
45
52
|
|
|
46
|
-
### 2.
|
|
53
|
+
### 2. Embeddings in bulk
|
|
47
54
|
|
|
48
55
|
```python
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
for result in client.submit_many(
|
|
57
|
+
"coreml_embed",
|
|
58
|
+
[{"input": chunked(doc)} for doc in corpus],
|
|
52
59
|
max_concurrent=16,
|
|
53
|
-
)
|
|
60
|
+
):
|
|
61
|
+
save(result.output) # results stream as they complete
|
|
54
62
|
```
|
|
55
63
|
|
|
56
|
-
### 3.
|
|
64
|
+
### 3. Background removal
|
|
57
65
|
|
|
58
66
|
```python
|
|
59
|
-
job = client.
|
|
60
|
-
top = client.result(job).output
|
|
67
|
+
job = client.images.remove_background("product-shot.png")
|
|
61
68
|
```
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
Also live: speech synthesis, image classification/detection/pose, barcode
|
|
71
|
+
reading, HEIC conversion — plus the generic `client.submit(workload_id,
|
|
72
|
+
payload)` for anything marked **live** in
|
|
73
|
+
[the catalog](https://commoncompute.ai/workloads).
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
job = client.translate(catalog_descriptions, target_lang="de")
|
|
67
|
-
```
|
|
75
|
+
### In preview
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
`client.translate(...)` and `client.video.transcode(...)` run on preview
|
|
78
|
+
capacity — functional, not yet GA.
|
|
70
79
|
|
|
71
|
-
|
|
72
|
-
job = client.images.remove_background("product-shot.png")
|
|
73
|
-
```
|
|
80
|
+
### Not live yet
|
|
74
81
|
|
|
75
|
-
|
|
76
|
-
`client.
|
|
77
|
-
|
|
82
|
+
`client.transcription.*`, `client.rerank(...)`, `client.images.generate(...)`,
|
|
83
|
+
`client.chat.*`, and `client.build.ios_test(...)` target workloads still
|
|
84
|
+
marked *coming soon*: the API refuses them with a clear
|
|
85
|
+
`workload_not_available` error (HTTP 409) rather than queueing a job that
|
|
86
|
+
won't run. They activate automatically as those lanes go live — watch
|
|
78
87
|
[the catalog](https://commoncompute.ai/workloads).
|
|
79
88
|
|
|
80
89
|
## Price before execution, hard caps, dry runs
|
|
@@ -148,48 +157,59 @@ raw request/response dicts instead of typed `Job`/`TaskResult` objects.
|
|
|
148
157
|
|
|
149
158
|
## CLI
|
|
150
159
|
|
|
151
|
-
`pip install "commoncompute[cli]"` installs the `
|
|
160
|
+
`pip install "commoncompute[cli]"` installs the `commoncompute` command.
|
|
161
|
+
|
|
162
|
+
> **Why not a short `cc`?** Because `cc` is the Unix C compiler
|
|
163
|
+
> (`/usr/bin/cc`). Shipping a binary by that name puts it ahead of the real
|
|
164
|
+
> compiler on `PATH` for anyone whose Python bin directory sorts first, and
|
|
165
|
+
> every build that shells out to `cc` then fails with a CLI usage error
|
|
166
|
+
> instead of compiling. So `commoncompute` is the only command installed. If
|
|
167
|
+
> you want the shorthand, opt in yourself:
|
|
168
|
+
>
|
|
169
|
+
> ```bash
|
|
170
|
+
> alias cc="commoncompute" # add to ~/.zshrc or ~/.bashrc
|
|
171
|
+
> ```
|
|
152
172
|
|
|
153
173
|
```bash
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
174
|
+
commoncompute login # stores the key locally
|
|
175
|
+
commoncompute quote vision_ocr --units 5 # price + ETA, no execution
|
|
176
|
+
commoncompute submit coreml_embed --payload '{"input":["hi"]}' --wait
|
|
177
|
+
commoncompute jobs list
|
|
178
|
+
commoncompute jobs get <id>
|
|
179
|
+
commoncompute balance
|
|
180
|
+
commoncompute receipts export --format csv --out receipts.csv
|
|
161
181
|
```
|
|
162
182
|
|
|
163
183
|
### Commands
|
|
164
184
|
|
|
165
185
|
| Command | What it does |
|
|
166
186
|
|---------|--------------|
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
187
|
-
| `
|
|
188
|
-
| `
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
191
|
-
|
|
192
|
-
`
|
|
187
|
+
| `commoncompute login` / `commoncompute logout` | Store / remove the API key (browser approval, or `--api-key`) |
|
|
188
|
+
| `commoncompute whoami` | Show the account behind the current key |
|
|
189
|
+
| `commoncompute balance` | Current workspace balance |
|
|
190
|
+
| `commoncompute usage` | Spend + call-count rollups over a date range (`--start`, `--end`, `--group-by`) |
|
|
191
|
+
| `commoncompute spend` | Total spend over the last `--days` N, grouped by workload |
|
|
192
|
+
| `commoncompute tier` | Current volume tier and the next threshold |
|
|
193
|
+
| `commoncompute workloads` | List available workloads |
|
|
194
|
+
| `commoncompute models` | List models (`--workload` to filter) |
|
|
195
|
+
| `commoncompute quote` | Price + ETA for a workload without submitting (`--units`, `--priority`, `--model`) |
|
|
196
|
+
| `commoncompute submit` | Submit one job (`--payload/-f`, `--model`, `--priority`, `--wait`, `--timeout`) |
|
|
197
|
+
| `commoncompute submit-many` | Submit a JSONL file of payloads; stream one result per line as NDJSON (`--input/-i`, `--max-concurrent`, `--no-wait`) |
|
|
198
|
+
| `commoncompute chat` | One-shot chat message to a model (`--model`, `--stream/--no-stream`) |
|
|
199
|
+
| `commoncompute embed` | Embed a single string (prints the vector length) |
|
|
200
|
+
| `commoncompute playground` | Open the web playground |
|
|
201
|
+
| `commoncompute jobs list` | Recent submissions, newest first (`--limit/-n`) |
|
|
202
|
+
| `commoncompute jobs get <id>` | Fetch one job |
|
|
203
|
+
| `commoncompute jobs wait <id>` | Poll a job to a terminal state (`--timeout/-t`) |
|
|
204
|
+
| `commoncompute jobs events <id>` | Event timeline for a job |
|
|
205
|
+
| `commoncompute jobs download <id>` | Download a job's result (`--out/-o`, else stdout) |
|
|
206
|
+
| `commoncompute keys list` / `create` / `revoke` | Manage API keys |
|
|
207
|
+
| `commoncompute receipts list` | Receipts for completed jobs (`--limit/-n`) |
|
|
208
|
+
| `commoncompute receipts get <id>` | Signed receipt for a single job |
|
|
209
|
+
| `commoncompute receipts export` | Export receipts as CSV or JSON (`--format/-f`, `--out/-o`, `--limit/-n`) |
|
|
210
|
+
| `commoncompute config path` / `show` / `set` / `unset` | Inspect and edit local settings (see below) |
|
|
211
|
+
|
|
212
|
+
`commoncompute --version` (or `-V`) prints the version. Every read command that renders a
|
|
193
213
|
table also accepts **`--json`** for plain, ANSI-free machine-readable output —
|
|
194
214
|
`whoami`, `balance`, `usage`, `spend`, `tier`, `workloads`, `models`, `quote`,
|
|
195
215
|
`submit`, `jobs list/get/wait/events`, `keys list`, and `receipts list`.
|
|
@@ -199,20 +219,20 @@ table also accepts **`--json`** for plain, ANSI-free machine-readable output —
|
|
|
199
219
|
Typer ships completion for bash, zsh, fish, and PowerShell:
|
|
200
220
|
|
|
201
221
|
```bash
|
|
202
|
-
|
|
203
|
-
|
|
222
|
+
commoncompute --install-completion # install for the current shell
|
|
223
|
+
commoncompute --show-completion # print the script to inspect or customise
|
|
204
224
|
```
|
|
205
225
|
|
|
206
226
|
### Exit codes
|
|
207
227
|
|
|
208
|
-
Scripts can branch on `
|
|
228
|
+
Scripts can branch on `commoncompute`'s exit status:
|
|
209
229
|
|
|
210
230
|
| Code | Meaning |
|
|
211
231
|
|------|---------|
|
|
212
232
|
| `0` | Success |
|
|
213
233
|
| `1` | API or runtime error (network, server, bad request) |
|
|
214
234
|
| `2` | Usage error — missing/invalid arguments, or no credentials found |
|
|
215
|
-
| `3` | The job reached a **failed** terminal state (`failed` / `dead_letter` / `cancelled`) — `
|
|
235
|
+
| `3` | The job reached a **failed** terminal state (`failed` / `dead_letter` / `cancelled`) — `commoncompute jobs wait` and `commoncompute submit --wait` only |
|
|
216
236
|
|
|
217
237
|
## Migrating from OpenAI (optional)
|
|
218
238
|
|
|
@@ -281,14 +301,14 @@ Environment variables take precedence over both files at runtime:
|
|
|
281
301
|
Inspect and edit the local config from the CLI:
|
|
282
302
|
|
|
283
303
|
```bash
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
304
|
+
commoncompute config path # print the config directory
|
|
305
|
+
commoncompute config show # settings + active credential source (key masked)
|
|
306
|
+
commoncompute config set base_url https://api.commoncompute.ai
|
|
307
|
+
commoncompute config set org my-workspace
|
|
308
|
+
commoncompute config unset org
|
|
289
309
|
```
|
|
290
310
|
|
|
291
|
-
Env vars still win at runtime — `
|
|
311
|
+
Env vars still win at runtime — `commoncompute config set` writes the file, but
|
|
292
312
|
`CC_BASE_URL` / `CC_ORG` override it for a given process.
|
|
293
313
|
|
|
294
314
|
Python 3.9+. Core dependencies: `httpx`, `pydantic`. MIT license.
|
|
@@ -11,33 +11,26 @@ Quickstart::
|
|
|
11
11
|
client = cc.Client(api_key="cc_live_...")
|
|
12
12
|
print(client.balance())
|
|
13
13
|
|
|
14
|
-
#
|
|
15
|
-
reply = client.chat.create(
|
|
16
|
-
model="qwen-2.5-7b",
|
|
17
|
-
messages=[{"role": "user", "content": "hi"}],
|
|
18
|
-
)
|
|
19
|
-
print(reply["choices"][0]["message"]["content"])
|
|
20
|
-
|
|
21
|
-
# Native job submission
|
|
14
|
+
# Native job submission (embeddings — live today)
|
|
22
15
|
job = client.jobs.submit(
|
|
23
16
|
workload_id="coreml_embed",
|
|
24
17
|
payload={"input": ["hello world"]},
|
|
25
18
|
)
|
|
26
19
|
result = client.jobs.wait(job["id"])
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
# OpenAI-compatible embeddings
|
|
22
|
+
vectors = client.embeddings.create(input=["hello world"], model="bge-base")
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
print(delta, end="", flush=True)
|
|
24
|
+
`client.chat.*` targets LLM workloads that are still marked *coming soon*
|
|
25
|
+
in the catalog — the API declines them with `workload_not_available`
|
|
26
|
+
(HTTP 409) until they go live. See https://commoncompute.ai/workloads.
|
|
34
27
|
"""
|
|
35
28
|
|
|
36
29
|
# MUST come before any submodule imports — _transport.py reads
|
|
37
30
|
# `commoncompute.__version__` at import time for the User-Agent header,
|
|
38
31
|
# and the previous ordering (`__version__` defined at the bottom) made
|
|
39
32
|
# every clean install of the SDK fail with a circular ImportError.
|
|
40
|
-
__version__ = "0.
|
|
33
|
+
__version__ = "0.3.0"
|
|
41
34
|
|
|
42
35
|
from .client import Client, AsyncClient
|
|
43
36
|
from .errors import (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Shared credential + config resolution for the SDK, CLI, and connect().
|
|
2
2
|
|
|
3
|
-
One module owns where keys and settings live, so ``Client()``,
|
|
3
|
+
One module owns where keys and settings live, so ``Client()``,
|
|
4
|
+
``commoncompute login``,
|
|
4
5
|
and ``commoncompute.connect()`` can never disagree again.
|
|
5
6
|
|
|
6
7
|
Canonical location (respects ``$CC_CONFIG_DIR``)::
|
|
@@ -30,7 +31,7 @@ import os
|
|
|
30
31
|
from pathlib import Path
|
|
31
32
|
from typing import Dict, Mapping, Optional, Tuple
|
|
32
33
|
|
|
33
|
-
#: Settings keys `
|
|
34
|
+
#: Settings keys `commoncompute config set` accepts (everything else is rejected).
|
|
34
35
|
SETTINGS_KEYS = ("base_url", "org")
|
|
35
36
|
|
|
36
37
|
|
|
@@ -143,13 +143,13 @@ class _BaseTransport:
|
|
|
143
143
|
if not resolved_key:
|
|
144
144
|
raise CommonComputeError(
|
|
145
145
|
"No API key. Run commoncompute.connect() (opens the browser, "
|
|
146
|
-
"no copy-paste) or `
|
|
146
|
+
"no copy-paste) or `commoncompute login` from a terminal — or pass "
|
|
147
147
|
"api_key=... / set CC_API_KEY.",
|
|
148
148
|
status_code=None,
|
|
149
149
|
code="missing_api_key",
|
|
150
150
|
)
|
|
151
151
|
self._api_key = resolved_key
|
|
152
|
-
# base_url / org: explicit arg → env → `
|
|
152
|
+
# base_url / org: explicit arg → env → `commoncompute config set` settings → default.
|
|
153
153
|
settings = _config.load_settings()
|
|
154
154
|
self._base_url = (
|
|
155
155
|
base_url
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
"""`
|
|
1
|
+
"""`commoncompute` command-line interface.
|
|
2
|
+
|
|
3
|
+
Installed as ``commoncompute`` via the pyproject entry point. A short ``cc``
|
|
4
|
+
alias is deliberately not installed — it would shadow the Unix C compiler
|
|
5
|
+
(``/usr/bin/cc``) and break builds that invoke it. Add
|
|
6
|
+
``alias cc="commoncompute"`` to your shell rc if you want the shorthand.
|
|
2
7
|
|
|
3
|
-
Installed as ``cc`` and ``commoncompute`` via the pyproject entry point.
|
|
4
8
|
Uses Typer for argparsing + Rich for pretty output. Reads credentials
|
|
5
9
|
from (in order): ``--api-key`` flag, ``CC_API_KEY`` env var, the canonical
|
|
6
10
|
credentials file at ``~/.config/commoncompute/credentials``, then the
|
|
@@ -11,7 +15,8 @@ Exit codes:
|
|
|
11
15
|
1 API / runtime error
|
|
12
16
|
2 usage error / missing credentials
|
|
13
17
|
3 a job reached a *failed* terminal state (failed / dead_letter /
|
|
14
|
-
cancelled) while waiting — ``
|
|
18
|
+
cancelled) while waiting — ``commoncompute jobs wait`` and
|
|
19
|
+
``commoncompute submit --wait``
|
|
15
20
|
"""
|
|
16
21
|
|
|
17
22
|
from __future__ import annotations
|
|
@@ -31,7 +36,7 @@ try:
|
|
|
31
36
|
from rich.panel import Panel
|
|
32
37
|
except ImportError: # CLI deps are the [cli] extra, not core deps
|
|
33
38
|
print(
|
|
34
|
-
"The `
|
|
39
|
+
"The `commoncompute` CLI needs the cli extra: pip install \"commoncompute[cli]\"",
|
|
35
40
|
file=sys.stderr,
|
|
36
41
|
)
|
|
37
42
|
raise SystemExit(2)
|
|
@@ -41,7 +46,7 @@ from .client import Client
|
|
|
41
46
|
from .errors import CommonComputeError
|
|
42
47
|
|
|
43
48
|
app = typer.Typer(
|
|
44
|
-
name="
|
|
49
|
+
name="commoncompute",
|
|
45
50
|
add_completion=True,
|
|
46
51
|
no_args_is_help=True,
|
|
47
52
|
help="Common Compute CLI — submit jobs, check spend, manage keys.",
|
|
@@ -63,7 +68,7 @@ err_console = Console(stderr=True, style="red")
|
|
|
63
68
|
def _version_callback(value: bool) -> None:
|
|
64
69
|
if value:
|
|
65
70
|
from . import __version__
|
|
66
|
-
print(f"
|
|
71
|
+
print(f"commoncompute {__version__}")
|
|
67
72
|
raise typer.Exit()
|
|
68
73
|
|
|
69
74
|
|
|
@@ -92,7 +97,9 @@ def _load_api_key(override: Optional[str] = None) -> Optional[str]:
|
|
|
92
97
|
def _client(api_key: Optional[str] = None) -> Client:
|
|
93
98
|
key = _load_api_key(api_key)
|
|
94
99
|
if not key:
|
|
95
|
-
err_console.print(
|
|
100
|
+
err_console.print(
|
|
101
|
+
"No API key found. Run [bold]commoncompute login[/bold] or set [bold]CC_API_KEY[/bold]."
|
|
102
|
+
)
|
|
96
103
|
raise typer.Exit(2)
|
|
97
104
|
try:
|
|
98
105
|
return Client(api_key=key)
|
|
@@ -159,7 +166,7 @@ def logout() -> None:
|
|
|
159
166
|
console.print("Nothing to remove.")
|
|
160
167
|
|
|
161
168
|
|
|
162
|
-
# ───
|
|
169
|
+
# ─── commoncompute config ───────────────────────────────────────────────
|
|
163
170
|
# Plain print() (not rich) on purpose: the output is meant for shells and
|
|
164
171
|
# scripts, and rich's 80-col soft-wrap would mangle long paths.
|
|
165
172
|
|
|
@@ -182,7 +189,7 @@ def config_show() -> None:
|
|
|
182
189
|
if key:
|
|
183
190
|
print(f"api key: {key[:8]}… (from {source})")
|
|
184
191
|
else:
|
|
185
|
-
print("api key: (none found — run `
|
|
192
|
+
print("api key: (none found — run `commoncompute login`)")
|
|
186
193
|
|
|
187
194
|
|
|
188
195
|
@config_app.command("set")
|
|
@@ -407,8 +414,10 @@ def estimate(
|
|
|
407
414
|
model: Optional[str] = typer.Option(None, "--model", "-m"),
|
|
408
415
|
as_json: bool = typer.Option(False, "--json", help="Raw JSON output."),
|
|
409
416
|
) -> None:
|
|
410
|
-
"""Deprecated alias for `
|
|
411
|
-
err_console.print(
|
|
417
|
+
"""Deprecated alias for `commoncompute quote` (kept for back-compat)."""
|
|
418
|
+
err_console.print(
|
|
419
|
+
"`commoncompute estimate` is deprecated; use `commoncompute quote` instead."
|
|
420
|
+
)
|
|
412
421
|
quote(workload=workload, units=units, priority=priority, model=model, as_json=as_json)
|
|
413
422
|
|
|
414
423
|
|
|
@@ -575,7 +584,7 @@ def jobs_status(
|
|
|
575
584
|
task_id: str,
|
|
576
585
|
as_json: bool = typer.Option(False, "--json", help="Raw JSON output (no ANSI)."),
|
|
577
586
|
) -> None:
|
|
578
|
-
"""Alias for `
|
|
587
|
+
"""Alias for `commoncompute jobs get`."""
|
|
579
588
|
jobs_get(task_id=task_id, as_json=as_json)
|
|
580
589
|
|
|
581
590
|
|
|
@@ -42,7 +42,11 @@ Source = "https://github.com/Ikaikaalika/commoncomputeai"
|
|
|
42
42
|
Changelog = "https://commoncompute.ai/changelog"
|
|
43
43
|
|
|
44
44
|
[project.scripts]
|
|
45
|
-
cc
|
|
45
|
+
# `commoncompute` is the only installed command. A short `cc` alias is
|
|
46
|
+
# deliberately NOT shipped: it shadows the Unix C compiler (/usr/bin/cc), so
|
|
47
|
+
# installing it into a PATH-early location silently breaks any build that
|
|
48
|
+
# invokes `cc`. Users who want the shorthand opt in themselves with
|
|
49
|
+
# `alias cc="commoncompute"`.
|
|
46
50
|
commoncompute = "commoncompute.cli:app"
|
|
47
51
|
|
|
48
52
|
[project.optional-dependencies]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|