commoncompute 0.2.0__tar.gz → 0.3.1__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 (21) hide show
  1. {commoncompute-0.2.0 → commoncompute-0.3.1}/.gitignore +1 -0
  2. {commoncompute-0.2.0 → commoncompute-0.3.1}/LICENSE +1 -1
  3. {commoncompute-0.2.0 → commoncompute-0.3.1}/PKG-INFO +90 -70
  4. {commoncompute-0.2.0 → commoncompute-0.3.1}/README.md +88 -68
  5. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/__init__.py +7 -14
  6. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/_async_client.py +3 -1
  7. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/_config.py +3 -2
  8. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/_generated_workloads.py +7 -4
  9. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/_transport.py +2 -2
  10. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/aws_batch.py +5 -6
  11. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/cli.py +59 -19
  12. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/client.py +19 -1
  13. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/connect.py +2 -1
  14. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/tasks.py +27 -0
  15. {commoncompute-0.2.0 → commoncompute-0.3.1}/pyproject.toml +6 -2
  16. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/_async_tasks.py +0 -0
  17. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/compat/__init__.py +0 -0
  18. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/compat/openai.py +0 -0
  19. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/errors.py +0 -0
  20. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/models.py +0 -0
  21. {commoncompute-0.2.0 → commoncompute-0.3.1}/commoncompute/py.typed +0 -0
@@ -3,6 +3,7 @@ node_modules/
3
3
  dist/
4
4
  coverage/
5
5
  .wrangler/
6
+ .wrangler.drifted-backup-*/
6
7
  .pytest_cache/
7
8
  __pycache__/
8
9
  *.pyc
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Common Compute, Inc.
3
+ Copyright (c) 2026 Common Compute LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commoncompute
3
- Version: 0.2.0
3
+ Version: 0.3.1
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
7
- Project-URL: Source, https://github.com/Ikaikaalika/commoncomputeai
7
+ Project-URL: Source, https://github.com/commoncompute/sdk
8
8
  Project-URL: Changelog, https://commoncompute.ai/changelog
9
9
  Author-email: Common Compute <support@commoncompute.ai>
10
10
  License: MIT
@@ -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 `cc` command line
48
- cc login # opens the browser — no key to copy-paste
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
- `cc login` (or `commoncompute.connect()` from a script or notebook) opens an
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.transcription.create("s3://my-bucket/meeting.mp3", timestamps=True)
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
- ## Examples
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. Transcription in bulk
88
+ ### 2. Embeddings in bulk
82
89
 
83
90
  ```python
84
- jobs = client.transcription.create_many(
85
- [f"s3://recordings/call-{i}.mp3" for i in range(200)],
86
- language="en",
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. Reranking — sharpen RAG retrieval
99
+ ### 3. Background removal
92
100
 
93
101
  ```python
94
- job = client.rerank("what is the neural engine?", documents, top_n=5)
95
- top = client.result(job).output
102
+ job = client.images.remove_background("product-shot.png")
96
103
  ```
97
104
 
98
- ### 4. Translation
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
- ```python
101
- job = client.translate(catalog_descriptions, target_lang="de")
102
- ```
110
+ ### In preview
103
111
 
104
- ### 5. Background removal
112
+ `client.translate(...)` and `client.video.transcode(...)` run on preview
113
+ capacity — functional, not yet GA.
105
114
 
106
- ```python
107
- job = client.images.remove_background("product-shot.png")
108
- ```
115
+ ### Not live yet
109
116
 
110
- Also available: `client.video.transcode(...)`, `client.build.ios_test(...)`,
111
- `client.images.generate(...)`, `client.embeddings.create(...)`, and the
112
- generic `client.submit(workload_id, payload)` for anything in
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 `cc` command.
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
- cc login # stores the key locally
190
- cc quote vision_ocr --units 5 # price + ETA, no execution
191
- cc submit coreml_embed --payload '{"input":["hi"]}' --wait
192
- cc jobs list
193
- cc jobs get <id>
194
- cc balance
195
- cc receipts export --format csv --out receipts.csv
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
- | `cc login` / `cc logout` | Store / remove the API key (browser approval, or `--api-key`) |
203
- | `cc whoami` | Show the account behind the current key |
204
- | `cc balance` | Current workspace balance |
205
- | `cc usage` | Spend + call-count rollups over a date range (`--start`, `--end`, `--group-by`) |
206
- | `cc spend` | Total spend over the last `--days` N, grouped by workload |
207
- | `cc tier` | Current volume tier and the next threshold |
208
- | `cc workloads` | List available workloads |
209
- | `cc models` | List models (`--workload` to filter) |
210
- | `cc quote` | Price + ETA for a workload without submitting (`--units`, `--priority`, `--model`) |
211
- | `cc submit` | Submit one job (`--payload/-f`, `--model`, `--priority`, `--wait`, `--timeout`) |
212
- | `cc submit-many` | Submit a JSONL file of payloads; stream one result per line as NDJSON (`--input/-i`, `--max-concurrent`, `--no-wait`) |
213
- | `cc chat` | One-shot chat message to a model (`--model`, `--stream/--no-stream`) |
214
- | `cc embed` | Embed a single string (prints the vector length) |
215
- | `cc playground` | Open the web playground |
216
- | `cc jobs list` | Recent submissions, newest first (`--limit/-n`) |
217
- | `cc jobs get <id>` | Fetch one job |
218
- | `cc jobs wait <id>` | Poll a job to a terminal state (`--timeout/-t`) |
219
- | `cc jobs events <id>` | Event timeline for a job |
220
- | `cc jobs download <id>` | Download a job's result (`--out/-o`, else stdout) |
221
- | `cc keys list` / `create` / `revoke` | Manage API keys |
222
- | `cc receipts list` | Receipts for completed jobs (`--limit/-n`) |
223
- | `cc receipts get <id>` | Signed receipt for a single job |
224
- | `cc receipts export` | Export receipts as CSV or JSON (`--format/-f`, `--out/-o`, `--limit/-n`) |
225
- | `cc config path` / `show` / `set` / `unset` | Inspect and edit local settings (see below) |
226
-
227
- `cc --version` (or `-V`) prints the version. Every read command that renders a
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
- cc --install-completion # install for the current shell
238
- cc --show-completion # print the script to inspect or customise
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 `cc`'s exit status:
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`) — `cc jobs wait` and `cc submit --wait` only |
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
- cc config path # print the config directory
320
- cc config show # settings + active credential source (key masked)
321
- cc config set base_url https://api.commoncompute.ai
322
- cc config set org my-workspace
323
- cc config unset org
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 — `cc config set` writes the file, but
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 `cc` command line
13
- cc login # opens the browser — no key to copy-paste
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
- `cc login` (or `commoncompute.connect()` from a script or notebook) opens an
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.transcription.create("s3://my-bucket/meeting.mp3", timestamps=True)
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
- ## Examples
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. Transcription in bulk
53
+ ### 2. Embeddings in bulk
47
54
 
48
55
  ```python
49
- jobs = client.transcription.create_many(
50
- [f"s3://recordings/call-{i}.mp3" for i in range(200)],
51
- language="en",
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. Reranking — sharpen RAG retrieval
64
+ ### 3. Background removal
57
65
 
58
66
  ```python
59
- job = client.rerank("what is the neural engine?", documents, top_n=5)
60
- top = client.result(job).output
67
+ job = client.images.remove_background("product-shot.png")
61
68
  ```
62
69
 
63
- ### 4. Translation
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
- ```python
66
- job = client.translate(catalog_descriptions, target_lang="de")
67
- ```
75
+ ### In preview
68
76
 
69
- ### 5. Background removal
77
+ `client.translate(...)` and `client.video.transcode(...)` run on preview
78
+ capacity — functional, not yet GA.
70
79
 
71
- ```python
72
- job = client.images.remove_background("product-shot.png")
73
- ```
80
+ ### Not live yet
74
81
 
75
- Also available: `client.video.transcode(...)`, `client.build.ios_test(...)`,
76
- `client.images.generate(...)`, `client.embeddings.create(...)`, and the
77
- generic `client.submit(workload_id, payload)` for anything in
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 `cc` command.
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
- cc login # stores the key locally
155
- cc quote vision_ocr --units 5 # price + ETA, no execution
156
- cc submit coreml_embed --payload '{"input":["hi"]}' --wait
157
- cc jobs list
158
- cc jobs get <id>
159
- cc balance
160
- cc receipts export --format csv --out receipts.csv
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
- | `cc login` / `cc logout` | Store / remove the API key (browser approval, or `--api-key`) |
168
- | `cc whoami` | Show the account behind the current key |
169
- | `cc balance` | Current workspace balance |
170
- | `cc usage` | Spend + call-count rollups over a date range (`--start`, `--end`, `--group-by`) |
171
- | `cc spend` | Total spend over the last `--days` N, grouped by workload |
172
- | `cc tier` | Current volume tier and the next threshold |
173
- | `cc workloads` | List available workloads |
174
- | `cc models` | List models (`--workload` to filter) |
175
- | `cc quote` | Price + ETA for a workload without submitting (`--units`, `--priority`, `--model`) |
176
- | `cc submit` | Submit one job (`--payload/-f`, `--model`, `--priority`, `--wait`, `--timeout`) |
177
- | `cc submit-many` | Submit a JSONL file of payloads; stream one result per line as NDJSON (`--input/-i`, `--max-concurrent`, `--no-wait`) |
178
- | `cc chat` | One-shot chat message to a model (`--model`, `--stream/--no-stream`) |
179
- | `cc embed` | Embed a single string (prints the vector length) |
180
- | `cc playground` | Open the web playground |
181
- | `cc jobs list` | Recent submissions, newest first (`--limit/-n`) |
182
- | `cc jobs get <id>` | Fetch one job |
183
- | `cc jobs wait <id>` | Poll a job to a terminal state (`--timeout/-t`) |
184
- | `cc jobs events <id>` | Event timeline for a job |
185
- | `cc jobs download <id>` | Download a job's result (`--out/-o`, else stdout) |
186
- | `cc keys list` / `create` / `revoke` | Manage API keys |
187
- | `cc receipts list` | Receipts for completed jobs (`--limit/-n`) |
188
- | `cc receipts get <id>` | Signed receipt for a single job |
189
- | `cc receipts export` | Export receipts as CSV or JSON (`--format/-f`, `--out/-o`, `--limit/-n`) |
190
- | `cc config path` / `show` / `set` / `unset` | Inspect and edit local settings (see below) |
191
-
192
- `cc --version` (or `-V`) prints the version. Every read command that renders a
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
- cc --install-completion # install for the current shell
203
- cc --show-completion # print the script to inspect or customise
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 `cc`'s exit status:
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`) — `cc jobs wait` and `cc submit --wait` only |
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
- cc config path # print the config directory
285
- cc config show # settings + active credential source (key masked)
286
- cc config set base_url https://api.commoncompute.ai
287
- cc config set org my-workspace
288
- cc config unset org
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 — `cc config set` writes the file, but
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
- # OpenAI-compatible chat
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
- Streaming chat::
21
+ # OpenAI-compatible embeddings
22
+ vectors = client.embeddings.create(input=["hello world"], model="bge-base")
29
23
 
30
- for chunk in client.chat.stream(model="qwen-2.5-7b",
31
- messages=[{"role": "user", "content": "hi"}]):
32
- delta = chunk["choices"][0].get("delta", {}).get("content", "")
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.2.0"
33
+ __version__ = "0.3.1"
41
34
 
42
35
  from .client import Client, AsyncClient
43
36
  from .errors import (
@@ -278,8 +278,10 @@ class _KeysAsync:
278
278
  async def list(self) -> list[dict[str, Any]]:
279
279
  return (await self._t.request("GET", "/v1/me/keys")).get("keys", [])
280
280
 
281
- async def create(self, *, name: str, mode: str = "live", scopes: "Optional[Sequence[str]]" = None) -> dict[str, Any]:
281
+ async def create(self, *, name: str, mode: str = "live", scopes: "Optional[Sequence[str]]" = None, password: "Optional[str]" = None) -> dict[str, Any]:
282
282
  body: dict[str, Any] = {"name": name, "mode": mode}
283
+ if password:
284
+ body["password"] = password
283
285
  if scopes:
284
286
  body["scopes"] = scopes
285
287
  return await self._t.request("POST", "/v1/me/keys", json_body=body)
@@ -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()``, ``cc login``,
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 `cc config set` accepts (everything else is rejected).
34
+ #: Settings keys `commoncompute config set` accepts (everything else is rejected).
34
35
  SETTINGS_KEYS = ("base_url", "org")
35
36
 
36
37
 
@@ -1,7 +1,10 @@
1
- # @generated by packages/workloads/codegen/emit-sdk-workloads.ts — DO NOT EDIT.
2
- # Regenerate: npx tsx packages/workloads/codegen/emit-sdk-workloads.ts
3
- # Source of truth: packages/workloads (the shared catalog). CI fails if this
4
- # file drifts from the catalog (see tests/unit/workloads-parity.test.ts).
1
+ # @generated from Common Compute's internal workload catalog — DO NOT EDIT.
2
+ #
3
+ # This file is emitted by an internal codegen step and is not regenerable from
4
+ # this repository. Edits here will be overwritten; the catalog is the source of
5
+ # truth and drift is caught before release.
6
+ #
7
+ # Contains workload IDs and image-name routing heuristics only.
5
8
  from __future__ import annotations
6
9
 
7
10
  # Every workload id in the catalog. Used to decide whether a jobDefinition head
@@ -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 `cc login` from a terminal — or pass "
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 → `cc config set` settings → default.
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
@@ -103,11 +103,10 @@ def _to_iso(ms: Optional[int]) -> Optional[str]:
103
103
  # Heuristic: anything containing one of these workload ids gets routed
104
104
  # directly. Otherwise we default to ``coreml_embed`` (the most common
105
105
  # batch workload migrated from AWS Batch + bge-* embeddings pipelines).
106
- # Workload identity comes from the generated catalog mirror so this shim
107
- # resolves jobDefinitions identically to the wire shim (apps/aws-shim) and the
108
- # Node SDK. The previous hand-maintained set had drifted to 12 of the catalog's
109
- # 24 workloads. Regenerate with:
110
- # npx tsx packages/workloads/codegen/emit-sdk-workloads.ts
106
+ # Workload identity comes from the generated catalog mirror
107
+ # (``_generated_workloads.py``) so this shim resolves jobDefinitions
108
+ # identically to the server side and to the Node SDK, instead of drifting
109
+ # from a hand-maintained list.
111
110
  from ._generated_workloads import IMAGE_PATTERNS as _IMAGE_PATTERN_SOURCES
112
111
  from ._generated_workloads import KNOWN_WORKLOAD_IDS as _KNOWN_WORKLOADS
113
112
 
@@ -403,7 +402,7 @@ class BatchClient:
403
402
  """Mirror AWS describe_jobs — returns ``{"jobs": [...]}``.
404
403
 
405
404
  Just-submitted jobs may not be queryable for ~100ms while the
406
- underlying D1 row propagates across the worker's read replicas.
405
+ underlying row propagates across the backing datastore's read replicas.
407
406
  We absorb a single 404 by retrying once after 250ms, which is
408
407
  enough to mask the eventual-consistency window in practice."""
409
408
  out: list[dict[str, Any]] = []
@@ -1,6 +1,10 @@
1
- """`cc` command-line interface.
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 — ``cc jobs wait`` and ``cc submit --wait``
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 `cc` CLI needs the cli extra: pip install \"commoncompute[cli]\"",
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="cc",
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"cc {__version__}")
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("No API key found. Run [bold]cc login[/bold] or set [bold]CC_API_KEY[/bold].")
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
- # ─── cc config ──────────────────────────────────────────────────────────
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 `cc login`)")
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 `cc quote` (kept for back-compat)."""
411
- err_console.print("`cc estimate` is deprecated; use `cc quote` instead.")
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
 
@@ -426,10 +435,46 @@ def _wait_job(client: Client, job_id: str, timeout: float, *, quiet: bool):
426
435
  return client.wait(job_id, timeout=timeout, on_progress=_tick)
427
436
 
428
437
 
438
+ def _parse_payload_arg(payload: str) -> object:
439
+ """Resolve --payload: @- (stdin), @path or bare path (file), or inline JSON.
440
+
441
+ The help has always said "path to JSON payload file", but the code only
442
+ honoured that with an @ prefix — a bare path fell through to json.loads()
443
+ and died with a raw JSONDecodeError traceback. Accept the documented
444
+ form, keep both @ forms, and turn every failure into a clean CLI error.
445
+ """
446
+ try:
447
+ if payload == "@-":
448
+ return json.load(sys.stdin)
449
+ if payload.startswith("@"):
450
+ return json.loads(Path(payload[1:]).read_text())
451
+ p = Path(payload)
452
+ if p.exists():
453
+ return json.loads(p.read_text())
454
+ # Not a file on disk — treat as inline JSON. A path-like string that
455
+ # simply doesn't exist gets a hint instead of a JSON parse error.
456
+ try:
457
+ return json.loads(payload)
458
+ except json.JSONDecodeError:
459
+ if payload.endswith(".json") or "/" in payload:
460
+ err_console.print(f"[red]Error:[/red] payload file not found: {payload}")
461
+ else:
462
+ err_console.print(f"[red]Error:[/red] --payload is not a file, not valid inline JSON: {payload!r}")
463
+ raise typer.Exit(2)
464
+ except typer.Exit:
465
+ raise
466
+ except json.JSONDecodeError as e:
467
+ err_console.print(f"[red]Error:[/red] invalid JSON in payload ({e.msg} at line {e.lineno}, column {e.colno})")
468
+ raise typer.Exit(2)
469
+ except OSError as e:
470
+ err_console.print(f"[red]Error:[/red] cannot read payload: {e}")
471
+ raise typer.Exit(2)
472
+
473
+
429
474
  @app.command()
430
475
  def submit(
431
476
  workload: str = typer.Argument(..., help="Workload id."),
432
- payload: Optional[str] = typer.Option(None, "--payload", "-f", help="Path to JSON payload file, or @- for stdin."),
477
+ payload: Optional[str] = typer.Option(None, "--payload", "-f", help="Path to a JSON payload file, @- for stdin, or an inline JSON string."),
433
478
  model: Optional[str] = typer.Option(None, "--model", "-m"),
434
479
  priority: str = typer.Option("standard", "--priority", "-p"),
435
480
  wait: bool = typer.Option(False, "--wait", help="Block until the job finishes."),
@@ -439,12 +484,7 @@ def submit(
439
484
  """Submit a native Common Compute job."""
440
485
  body: object = None
441
486
  if payload:
442
- if payload == "@-":
443
- body = json.load(sys.stdin)
444
- elif payload.startswith("@"):
445
- body = json.loads(Path(payload[1:]).read_text())
446
- else:
447
- body = json.loads(payload)
487
+ body = _parse_payload_arg(payload)
448
488
  c = _client()
449
489
  try:
450
490
  job = c.jobs.submit(workload, payload=body, model_id=model, priority=priority)
@@ -575,7 +615,7 @@ def jobs_status(
575
615
  task_id: str,
576
616
  as_json: bool = typer.Option(False, "--json", help="Raw JSON output (no ANSI)."),
577
617
  ) -> None:
578
- """Alias for `cc jobs get`."""
618
+ """Alias for `commoncompute jobs get`."""
579
619
  jobs_get(task_id=task_id, as_json=as_json)
580
620
 
581
621
 
@@ -263,10 +263,28 @@ class _KeysSync:
263
263
  def list(self) -> list[dict[str, Any]]:
264
264
  return self._t.request("GET", "/v1/me/keys").get("keys", [])
265
265
 
266
- def create(self, *, name: str, mode: str = "live", scopes: "Optional[Sequence[str]]" = None) -> dict[str, Any]:
266
+ def create(
267
+ self,
268
+ *,
269
+ name: str,
270
+ mode: str = "live",
271
+ scopes: "Optional[Sequence[str]]" = None,
272
+ password: "Optional[str]" = None,
273
+ ) -> dict[str, Any]:
274
+ """Create an API key.
275
+
276
+ Requires a signed-in *session* plus the account password. An API key
277
+ cannot create another API key (the server returns 403
278
+ ``api_key_cannot_mint``) — otherwise revoking a leaked key would not
279
+ revoke the keys it had spawned. Since this SDK normally authenticates
280
+ with an API key, most callers should create keys in the dashboard at
281
+ /app/api-keys instead.
282
+ """
267
283
  body: dict[str, Any] = {"name": name, "mode": mode}
268
284
  if scopes:
269
285
  body["scopes"] = scopes
286
+ if password:
287
+ body["password"] = password
270
288
  return self._t.request("POST", "/v1/me/keys", json_body=body)
271
289
 
272
290
  def revoke(self, key_id: str) -> None:
@@ -125,5 +125,6 @@ def connect(
125
125
  )
126
126
 
127
127
 
128
- # `cc.login()` reads naturally next to the CLI's `cc login`.
128
+ # `cc.login()` (import commoncompute as cc) reads naturally next to the
129
+ # CLI's `commoncompute login`.
129
130
  login = connect
@@ -27,12 +27,31 @@ from .models import Job, Quote, Receipt, TaskResult
27
27
 
28
28
  FileInput = Union[str, Path, bytes, io.BufferedReader]
29
29
 
30
+ # Schemes recognised as "this is a URI, not a local path". Only https:// can
31
+ # actually be fetched: the provider's download gate hard-rejects every other
32
+ # scheme (TrustedDownload.swift — "only https"), and http:// specifically is
33
+ # refused because a job input must not travel in the clear.
34
+ #
35
+ # The others stay in this tuple ON PURPOSE. Dropping them would make an s3://
36
+ # URI fall through to the local-path branch and raise a confusing
37
+ # "No such file: s3://bucket/key"; keeping them lets _file_payload reject the
38
+ # scheme by name, at submit time, instead of the job dispatching and failing
39
+ # on someone's Mac minutes later (2026-08-01 audit — the SDKs documented all
40
+ # five schemes and only one ever worked).
30
41
  _URI_SCHEMES = ("http://", "https://", "s3://", "r2://", "gs://")
42
+ _FETCHABLE_URI_SCHEMES = ("https://",)
31
43
 
32
44
 
33
45
  def _file_payload(f: FileInput, *, allowed_suffixes: Optional[Sequence[str]] = None) -> dict:
34
46
  """Normalise a file input into the job-payload contract."""
35
47
  if isinstance(f, str) and f.startswith(_URI_SCHEMES):
48
+ if not f.startswith(_FETCHABLE_URI_SCHEMES):
49
+ scheme = f.split("://", 1)[0]
50
+ raise UnsupportedFormatError(
51
+ f"{scheme}:// inputs are not supported — providers can only fetch https:// URLs. "
52
+ f"Pass a local path (the file is uploaded for you) or a presigned https:// URL.",
53
+ code="unsupported_input_scheme",
54
+ )
36
55
  return {"input_uri": f}
37
56
  if isinstance(f, (str, Path)):
38
57
  p = Path(f)
@@ -367,6 +386,14 @@ class Video(_TaskBase):
367
386
  max_spend_usd: Optional[float] = None,
368
387
  dry_run: bool = False,
369
388
  ) -> Union[Job, Quote]:
389
+ """Transcode a video with VideoToolbox hardware encoders.
390
+
391
+ ``output_format`` selects the codec (``"h264"`` / ``"hevc"`` /
392
+ ``"prores"``); ``codec=`` overrides it if both are given.
393
+ ``resolution`` is not yet implemented server-side — a job that sets
394
+ it fails fast with a clear error instead of silently encoding at
395
+ the source's native size.
396
+ """
370
397
  workload_id, payload, units, model_id = _transcode_request(
371
398
  input, output_format, resolution=resolution, codec=codec, output_minutes=output_minutes,
372
399
  )
@@ -38,11 +38,15 @@ dependencies = [
38
38
  [project.urls]
39
39
  Homepage = "https://commoncompute.ai"
40
40
  Documentation = "https://commoncompute.ai/docs"
41
- Source = "https://github.com/Ikaikaalika/commoncomputeai"
41
+ Source = "https://github.com/commoncompute/sdk"
42
42
  Changelog = "https://commoncompute.ai/changelog"
43
43
 
44
44
  [project.scripts]
45
- cc = "commoncompute.cli:app"
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]