muapi-cli 0.2.5__py3-none-any.whl

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.
muapi/utils.py ADDED
@@ -0,0 +1,202 @@
1
+ """Shared output, display, and download helpers — agent-friendly."""
2
+ import json
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Any, Optional
7
+ from urllib.parse import urlparse
8
+
9
+ import httpx
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.table import Table
13
+
14
+ from . import exitcodes
15
+
16
+ # ── Colour / NO_COLOR support ─────────────────────────────────────────────────
17
+ # Honour the NO_COLOR env var (https://no-color.org/) and --no-color flag.
18
+ # Both CI environments and agent pipelines typically set NO_COLOR=1.
19
+ _NO_COLOR = bool(os.environ.get("NO_COLOR") or os.environ.get("MUAPI_NO_COLOR"))
20
+
21
+ console = Console(stderr=True, no_color=_NO_COLOR) # status/progress → stderr
22
+ out = Console(no_color=_NO_COLOR) # actual output → stdout
23
+
24
+
25
+ def disable_color() -> None:
26
+ """Called when user passes --no-color flag."""
27
+ global console, out, _NO_COLOR
28
+ _NO_COLOR = True
29
+ console = Console(stderr=True, no_color=True)
30
+ out = Console(no_color=True)
31
+
32
+
33
+ # ── jq-style filtering ────────────────────────────────────────────────────────
34
+
35
+ def apply_jq(data: Any, expression: str) -> Any:
36
+ """Apply a simple jq-style expression to data.
37
+
38
+ Supports:
39
+ .key → dict field
40
+ .key.nested → nested dict fields
41
+ .[0] → list index
42
+ .[] → all list items (returns list)
43
+ .key[] → field then list
44
+ .key[0] → field then index
45
+ """
46
+ if not expression or expression == ".":
47
+ return data
48
+ # Strip leading dot
49
+ expr = expression.lstrip(".")
50
+ if not expr:
51
+ return data
52
+ return _jq_walk(data, expr)
53
+
54
+
55
+ def _jq_walk(data: Any, expr: str) -> Any:
56
+ if not expr:
57
+ return data
58
+ # Array index: [N]
59
+ if expr.startswith("["):
60
+ end = expr.index("]")
61
+ idx_str = expr[1:end]
62
+ rest = expr[end + 1:].lstrip(".")
63
+ if idx_str == "":
64
+ # .[] — all items
65
+ if not isinstance(data, list):
66
+ raise ValueError(f"Expected list for '[]', got {type(data).__name__}")
67
+ return [_jq_walk(item, rest) for item in data]
68
+ else:
69
+ idx = int(idx_str)
70
+ if not isinstance(data, list):
71
+ raise ValueError(f"Expected list for '[{idx}]', got {type(data).__name__}")
72
+ return _jq_walk(data[idx], rest)
73
+ # Key access
74
+ if "." in expr:
75
+ key, rest = expr.split(".", 1)
76
+ # Handle key[] inline
77
+ if key.endswith("[]"):
78
+ key = key[:-2]
79
+ val = data[key]
80
+ return [_jq_walk(item, rest) if rest else item for item in val]
81
+ if key.endswith("]"):
82
+ bracket = key.index("[")
83
+ idx = int(key[bracket + 1:-1])
84
+ key = key[:bracket]
85
+ return _jq_walk(data[key][idx], rest)
86
+ return _jq_walk(data[key], rest)
87
+ else:
88
+ key = expr
89
+ if key.endswith("[]"):
90
+ return data[key[:-2]]
91
+ if key.endswith("]"):
92
+ bracket = key.index("[")
93
+ idx = int(key[bracket + 1:-1])
94
+ return data[key[:bracket]][idx]
95
+ return data[key]
96
+
97
+
98
+ # ── JSON output ───────────────────────────────────────────────────────────────
99
+
100
+ def print_json(data: Any, jq: Optional[str] = None) -> None:
101
+ if jq:
102
+ try:
103
+ data = apply_jq(data, jq)
104
+ except Exception as e:
105
+ error_exit(f"jq filter error: {e}", exitcodes.VALIDATION)
106
+ if isinstance(data, (dict, list)):
107
+ out.print_json(json.dumps(data))
108
+ else:
109
+ out.print(json.dumps(data))
110
+
111
+
112
+ def print_result(
113
+ result: dict,
114
+ output_json: bool,
115
+ label: str = "Result",
116
+ jq: Optional[str] = None,
117
+ ) -> None:
118
+ if output_json or jq:
119
+ print_json(result, jq)
120
+ return
121
+ status = result.get("status", "")
122
+ outputs = result.get("outputs", [])
123
+
124
+ lines = []
125
+ if status:
126
+ color = "green" if status == "completed" else ("red" if status == "failed" else "yellow")
127
+ lines.append(f"[bold]Status:[/bold] [{color}]{status}[/{color}]")
128
+ if req_id := result.get("request_id"):
129
+ lines.append(f"[bold]Request ID:[/bold] {req_id}")
130
+ if outputs:
131
+ lines.append("[bold]Outputs:[/bold]")
132
+ for o in outputs:
133
+ lines.append(f" [cyan]{o}[/cyan]")
134
+
135
+ if lines:
136
+ out.print(Panel("\n".join(lines), title=f"[bold magenta]{label}[/bold magenta]"))
137
+ else:
138
+ out.print_json(json.dumps(result))
139
+
140
+
141
+ # ── Download ──────────────────────────────────────────────────────────────────
142
+
143
+ def download_outputs(result: dict, dest: str) -> None:
144
+ outputs = result.get("outputs", [])
145
+ if not outputs:
146
+ console.print("[yellow]No outputs to download.[/yellow]")
147
+ return
148
+ dest_path = Path(dest)
149
+ dest_path.mkdir(parents=True, exist_ok=True)
150
+ for i, url in enumerate(outputs):
151
+ filename = _filename_from_url(url, i)
152
+ target = dest_path / filename
153
+ console.print(f"Downloading [cyan]{url}[/cyan] → [green]{target}[/green]")
154
+ with httpx.stream("GET", url, follow_redirects=True) as r:
155
+ with open(target, "wb") as f:
156
+ for chunk in r.iter_bytes():
157
+ f.write(chunk)
158
+ console.print(f" [green]Saved[/green] {target}")
159
+
160
+
161
+ def _filename_from_url(url: str, index: int) -> str:
162
+ path = urlparse(url).path
163
+ name = path.split("/")[-1]
164
+ if not name or "." not in name:
165
+ name = f"output_{index}"
166
+ return name
167
+
168
+
169
+ # ── Errors ────────────────────────────────────────────────────────────────────
170
+
171
+ def error_exit(msg: str, code: int = exitcodes.ERROR) -> None:
172
+ """Print error to stderr and exit with a semantic exit code."""
173
+ console.print(f"[bold red]Error:[/bold red] {msg}")
174
+ sys.exit(code)
175
+
176
+
177
+ # ── Spinner ───────────────────────────────────────────────────────────────────
178
+
179
+ def spinner_status(msg: str):
180
+ return console.status(f"[bold cyan]{msg}[/bold cyan]", spinner="dots")
181
+
182
+
183
+ # ── Dry-run display ───────────────────────────────────────────────────────────
184
+
185
+ def print_dry_run(endpoint: str, payload: dict) -> None:
186
+ """Show what request would be sent without executing it."""
187
+ from .config import BASE_URL
188
+ out.print(Panel(
189
+ f"[bold]Method:[/bold] POST\n"
190
+ f"[bold]URL:[/bold] {BASE_URL}/{endpoint.lstrip('/')}\n"
191
+ f"[bold]Payload:[/bold]\n{json.dumps(payload, indent=2)}",
192
+ title="[bold yellow]Dry Run — no request sent[/bold yellow]",
193
+ ))
194
+
195
+
196
+ # ── Stdin helper ──────────────────────────────────────────────────────────────
197
+
198
+ def read_stdin_if_dash(value: Optional[str]) -> Optional[str]:
199
+ """If value is '-', read a line from stdin. Useful for piping prompts."""
200
+ if value == "-":
201
+ return sys.stdin.readline().strip()
202
+ return value
@@ -0,0 +1,337 @@
1
+ Metadata-Version: 2.4
2
+ Name: muapi-cli
3
+ Version: 0.2.5
4
+ Summary: Official CLI for muapi.ai — generative media at your fingertips
5
+ License: MIT
6
+ Requires-Python: >=3.9
7
+ Requires-Dist: httpx>=0.27.0
8
+ Requires-Dist: keyring>=24.0.0
9
+ Requires-Dist: rich>=13.0.0
10
+ Requires-Dist: typer>=0.12.0
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest; extra == 'dev'
13
+ Requires-Dist: pytest-asyncio; extra == 'dev'
14
+ Requires-Dist: respx; extra == 'dev'
15
+ Provides-Extra: release
16
+ Requires-Dist: pyinstaller>=6.0; extra == 'release'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # muapi CLI
20
+
21
+ Official command-line interface for [muapi.ai](https://muapi.ai) — generate images, videos, and audio directly from your terminal.
22
+
23
+ **Agent-first design** — every command works for both humans (colored output, tables) and AI agents (`--output-json`, `--jq` filtering, semantic exit codes, MCP server mode).
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ # npm (recommended — no Python required)
29
+ npm install -g muapi-cli
30
+
31
+ # pip
32
+ pip install muapi-cli
33
+
34
+ # or run without installing
35
+ npx muapi-cli --help
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```bash
41
+ # New user? Create an account
42
+ muapi auth register --email you@example.com --password "..."
43
+ muapi auth verify --email you@example.com --otp 123456
44
+ muapi auth login --email you@example.com --password "..."
45
+
46
+ # Or paste an existing API key
47
+ muapi auth configure --api-key "YOUR_KEY"
48
+
49
+ # Generate — pick a curated verb…
50
+ muapi image generate "a cyberpunk city at night" --model flux-dev
51
+ muapi video generate "a dog running on a beach" --model kling-master
52
+ muapi audio create "upbeat lo-fi hip hop for studying"
53
+
54
+ # …or run any model by endpoint name (schema-driven, covers the whole catalog)
55
+ muapi run flux-dev-image -p "a cyberpunk city at night"
56
+ muapi run seedance-2-text-to-video -p "drone shot over snowy peaks" -i duration=5
57
+ muapi run <model> -h # introspects the live OpenAPI schema
58
+
59
+ # Check balance
60
+ muapi account balance
61
+
62
+ # Wait for an existing job
63
+ muapi predict wait <request_id>
64
+ ```
65
+
66
+ ## Commands
67
+
68
+ ### `muapi auth`
69
+ | Command | Description |
70
+ |---------|-------------|
71
+ | `muapi auth register --email x --password y` | Create a new account (sends OTP) |
72
+ | `muapi auth verify --email x --otp 123456` | Verify email after registration |
73
+ | `muapi auth login --email x --password y` | Log in and save API key automatically |
74
+ | `muapi auth forgot-password --email x` | Send password reset OTP |
75
+ | `muapi auth reset-password --email x --otp y --password z` | Reset password |
76
+ | `muapi auth configure` | Manually save an API key |
77
+ | `muapi auth whoami` | Show current API key (masked) |
78
+ | `muapi auth logout` | Remove stored API key |
79
+
80
+ ### `muapi account`
81
+ | Command | Description |
82
+ |---------|-------------|
83
+ | `muapi account balance` | Show current credit balance |
84
+ | `muapi account topup --amount 20` | Add credits via Stripe checkout |
85
+
86
+ ### `muapi keys`
87
+ | Command | Description |
88
+ |---------|-------------|
89
+ | `muapi keys list` | List all API keys on your account |
90
+ | `muapi keys create --name label` | Create a new API key (shown once) |
91
+ | `muapi keys delete <id>` | Delete an API key by ID |
92
+
93
+ ### `muapi image`
94
+ | Command | Description |
95
+ |---------|-------------|
96
+ | `muapi image generate <prompt>` | Text-to-image generation |
97
+ | `muapi image edit <prompt> --image <url>` | Image-to-image editing |
98
+ | `muapi image models` | List available models |
99
+
100
+ **Models:** `flux-dev`, `flux-schnell`, `flux-kontext-dev/pro/max`, `hidream-fast/dev/full`, `wan2.1`, `reve`, `gpt4o`, `midjourney`, `seedream`, `qwen`
101
+
102
+ ### `muapi video`
103
+ | Command | Description |
104
+ |---------|-------------|
105
+ | `muapi video generate <prompt>` | Text-to-video generation |
106
+ | `muapi video from-image <prompt> --image <url>` | Image-to-video animation |
107
+ | `muapi video models` | List available models |
108
+
109
+ **Models:** `veo3`, `veo3-fast`, `kling-master`, `kling-std`, `kling-pro`, `wan2.1/2.2`, `seedance-pro/lite`, `hunyuan`, `runway`, `pixverse`, `vidu`, `minimax-std/pro`
110
+
111
+ ### `muapi audio`
112
+ | Command | Description |
113
+ |---------|-------------|
114
+ | `muapi audio create <prompt>` | Create music with Suno |
115
+ | `muapi audio remix <song-id>` | Remix an existing Suno song |
116
+ | `muapi audio extend <song-id>` | Extend a Suno song |
117
+ | `muapi audio from-text <prompt>` | Generate audio with MMAudio |
118
+ | `muapi audio from-video <video-url>` | Add AI audio to a video |
119
+
120
+ ### `muapi enhance`
121
+ | Command | Description |
122
+ |---------|-------------|
123
+ | `muapi enhance upscale <url>` | AI image upscaling |
124
+ | `muapi enhance bg-remove <url>` | Remove background |
125
+ | `muapi enhance face-swap --source <url> --target <url>` | Face swap image/video |
126
+ | `muapi enhance skin <url>` | Skin enhancement |
127
+ | `muapi enhance colorize <url>` | Colorize B&W photo |
128
+ | `muapi enhance ghibli <url>` | Ghibli anime style |
129
+ | `muapi enhance anime <url>` | Anime style conversion |
130
+ | `muapi enhance extend <url>` | Outpaint/extend image |
131
+ | `muapi enhance product-shot <url>` | Professional product photo |
132
+ | `muapi enhance erase <url> --mask <url>` | Object removal |
133
+
134
+ ### `muapi edit`
135
+ | Command | Description |
136
+ |---------|-------------|
137
+ | `muapi edit effects --video <url> --effect <name>` | AI video/image effects |
138
+ | `muapi edit lipsync --video <url> --audio <url>` | Lip sync to audio |
139
+ | `muapi edit dance --image <url> --video <url>` | Make person dance |
140
+ | `muapi edit dress --image <url>` | Change clothing |
141
+ | `muapi edit clipping <video-url>` | AI highlight extraction |
142
+
143
+ ### `muapi run` — generic, schema-driven runner
144
+
145
+ Reaches **any** model in the muapi.ai catalog by endpoint name, even ones not covered by the curated `image / video / audio / enhance / edit` verbs. The input schema is fetched from the live OpenAPI spec, so `muapi run <model> -h` always reflects the real, current parameters.
146
+
147
+ | Command | Description |
148
+ |---------|-------------|
149
+ | `muapi run <model> -h` | Print model-specific inputs from the live OpenAPI schema |
150
+ | `muapi run <model> -p "..."` | Run with a prompt |
151
+ | `muapi run <model> -p "..." -i k=v -i k=v` | Pass arbitrary inputs (JSON-parsed when valid) |
152
+ | `muapi run <model> --input-file inputs.json` | Inputs from a JSON file |
153
+ | `muapi run <model> ... --dry-run` | Show the request body without sending |
154
+
155
+ `<model>` accepts either a real endpoint slug (`flux-dev-image`, `nano-banana-2`, `seedance-2-text-to-video`) or a short alias from the curated tables (`flux-dev`, `seedream`, `kling-master`).
156
+
157
+ **Merge order for inputs** (later wins): `--input-file` → `-i k=v` → `-p prompt`.
158
+
159
+ ```bash
160
+ # Discover a model's real inputs
161
+ muapi run nano-banana-2 -h
162
+
163
+ # Run it
164
+ muapi run nano-banana-2 -p "a logo for a coffee shop" -i num_images=2 --download ./out
165
+
166
+ # Pipe-safe JSON
167
+ muapi run flux-dev-image -p "..." --output-json --jq '.outputs[0]'
168
+ ```
169
+
170
+ ### `muapi predict`
171
+ | Command | Description |
172
+ |---------|-------------|
173
+ | `muapi predict result <id>` | Fetch current status (no polling) |
174
+ | `muapi predict wait <id>` | Wait until complete |
175
+
176
+ ### `muapi upload`
177
+ | Command | Description |
178
+ |---------|-------------|
179
+ | `muapi upload file <path>` | Upload a local file → get hosted URL |
180
+
181
+ ### `muapi models`
182
+ | Command | Description |
183
+ |---------|-------------|
184
+ | `muapi models list` | List all models |
185
+ | `muapi models list --category video` | Filter by category |
186
+
187
+ ### `muapi config`
188
+ | Command | Description |
189
+ |---------|-------------|
190
+ | `muapi config set <key> <value>` | Set a persistent default |
191
+ | `muapi config get <key>` | Read a config value |
192
+ | `muapi config list` | Show all config |
193
+
194
+ **Useful keys:** `output` (json/human), `model.image`, `model.video`, `no_color` (true/false)
195
+
196
+ ### `muapi docs`
197
+ | Command | Description |
198
+ |---------|-------------|
199
+ | `muapi docs openapi` | Fetch the full OpenAPI spec |
200
+ | `muapi docs open` | Open Swagger UI in browser |
201
+
202
+ ### `muapi mcp`
203
+ | Command | Description |
204
+ |---------|-------------|
205
+ | `muapi mcp serve` | Start MCP server (stdio) for AI agents |
206
+
207
+ ## Global Options
208
+
209
+ | Flag | Description |
210
+ |------|-------------|
211
+ | `--wait / --no-wait` | Poll until done (default: `--wait`) |
212
+ | `--output-json` / `-j` | Print raw JSON response |
213
+ | `--jq <expr>` | Filter JSON output (e.g. `'.outputs[0]'`) |
214
+ | `--download <dir>` / `-d` | Auto-download outputs to directory |
215
+ | `--no-color` | Disable colored output |
216
+
217
+ ## Environment Variables
218
+
219
+ | Variable | Description |
220
+ |----------|-------------|
221
+ | `MUAPI_API_KEY` | API key (overrides keychain/config) |
222
+ | `MUAPI_BASE_URL` | Override API base URL |
223
+ | `NO_COLOR` | Disable colored output |
224
+
225
+ ## Exit Codes
226
+
227
+ | Code | Meaning |
228
+ |------|---------|
229
+ | `0` | Success |
230
+ | `1` | General error |
231
+ | `3` | Authentication error |
232
+ | `4` | Rate limited |
233
+ | `5` | Not found |
234
+ | `6` | Billing error |
235
+ | `7` | Timeout |
236
+ | `8` | Validation error |
237
+
238
+ ## MCP Server
239
+
240
+ muapi supports two MCP transport modes. Both expose the same **19 tools**: image generate/edit, video generate/from-image, audio create/from-text, enhance (upscale/bg-remove/face-swap/ghibli), edit lipsync/clipping, predict result, upload file, keys list/create/delete, account balance/topup.
241
+
242
+ ### Option 1 — Hosted (Recommended, no CLI required)
243
+
244
+ The hosted MCP server at `https://api.muapi.ai/mcp` uses the standard Streamable HTTP transport. Any MCP client can connect with just your API key — no CLI install needed.
245
+
246
+ **Claude Code:**
247
+ ```bash
248
+ claude mcp add --transport http muapi \
249
+ https://api.muapi.ai/mcp \
250
+ --header "Authorization: Bearer YOUR_MUAPI_KEY"
251
+ ```
252
+
253
+ **Cursor** — add to `mcp.json` (`Cmd+Shift+P` → Open MCP settings):
254
+ ```json
255
+ {
256
+ "mcpServers": {
257
+ "muapi": {
258
+ "url": "https://api.muapi.ai/mcp",
259
+ "headers": { "Authorization": "Bearer YOUR_MUAPI_KEY" }
260
+ }
261
+ }
262
+ }
263
+ ```
264
+
265
+ **Windsurf** — open **Settings → MCP**:
266
+ ```json
267
+ {
268
+ "mcpServers": {
269
+ "muapi": {
270
+ "serverUrl": "https://api.muapi.ai/mcp",
271
+ "headers": { "Authorization": "Bearer YOUR_MUAPI_KEY" }
272
+ }
273
+ }
274
+ }
275
+ ```
276
+
277
+ ### Option 2 — stdio via CLI (Claude Desktop)
278
+
279
+ Run the CLI as a local stdio MCP server. Requires the CLI to be installed.
280
+
281
+ ```bash
282
+ muapi mcp serve
283
+ ```
284
+
285
+ **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
286
+ ```json
287
+ {
288
+ "mcpServers": {
289
+ "muapi": {
290
+ "command": "muapi",
291
+ "args": ["mcp", "serve"],
292
+ "env": { "MUAPI_API_KEY": "your-key-here" }
293
+ }
294
+ }
295
+ }
296
+ ```
297
+
298
+ **Any stdio-compatible client** — use the `command` + `args` pattern above, substituting your client's config format.
299
+
300
+ > For more details on the self-hosted MCP server see [muapi-mcp-server](https://github.com/SamurAIGPT/muapi-mcp-server).
301
+
302
+ ## Agentic Pipeline Examples
303
+
304
+ ```bash
305
+ # Full onboarding without human intervention
306
+ muapi auth register --email agent@example.com --password "secret"
307
+ muapi auth verify --email agent@example.com --otp 123456
308
+ muapi auth login --email agent@example.com --password "secret"
309
+ muapi account balance --output-json
310
+ muapi account topup --amount 10 --output-json --no-open
311
+
312
+ # Submit async, capture request_id, poll when ready
313
+ REQUEST_ID=$(muapi video generate "a dog on a beach" \
314
+ --model kling-master --no-wait --output-json --jq '.request_id' | tr -d '"')
315
+ muapi predict wait "$REQUEST_ID" --download ./outputs
316
+
317
+ # Chain: upload → edit → download
318
+ URL=$(muapi upload file ./photo.jpg --output-json --jq '.url' | tr -d '"')
319
+ muapi image edit "make it look like a painting" --image "$URL" \
320
+ --model flux-kontext-pro --download ./outputs
321
+
322
+ # Rotate API keys programmatically
323
+ NEW_KEY=$(muapi keys create --name "ci-$(date +%Y%m%d)" --output-json --jq '.api_key' | tr -d '"')
324
+ OLD_ID=$(muapi keys list --output-json --jq '.[0].id')
325
+ muapi keys delete "$OLD_ID" --yes
326
+
327
+ # Discover available endpoints
328
+ muapi docs openapi --jq '.paths | keys[]'
329
+ ```
330
+
331
+ ## Shell Completions
332
+
333
+ ```bash
334
+ muapi --install-completion bash
335
+ muapi --install-completion zsh
336
+ muapi --install-completion fish
337
+ ```
@@ -0,0 +1,29 @@
1
+ muapi/__init__.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
2
+ muapi/client.py,sha256=5BH5qSIPJ30lQbeMumzq6-PqLEm9rWpbKtwk_szJqI0,4240
3
+ muapi/config.py,sha256=SfG4Pk1BPmMrZHf3IacQn6HTkl7Wx1phRU2bHnaH-Kg,3218
4
+ muapi/dynamic_help.py,sha256=5vNhFYRWGb-a8c27CnG28ZKAxBgFgatdQ17pF3fgJOc,5324
5
+ muapi/exitcodes.py,sha256=tK9T8x6vCL36tiXRl_TotF9wVIxFsBvHpdv_XLgJOCk,596
6
+ muapi/main.py,sha256=h-wcOlvgU8rd0oJLLcKzjGjez6p8Gzgx6BDYtan2MdA,3973
7
+ muapi/schema_introspect.py,sha256=OqqzJRABJCLZWcFa70T3UzEvl3W3xH54SXYpk9Cv7hM,6091
8
+ muapi/utils.py,sha256=oalnyiNrm60FKtZ0B4qZ-RhW4WdjPtsqVBmV4ikeQvc,7800
9
+ muapi/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ muapi/commands/account.py,sha256=s867RrLsflg3COpMOxtplWeR7pssYzf2010nZSXY6Ew,3180
11
+ muapi/commands/audio.py,sha256=tTZHNaw5F6SBP84kKhoLaVtSNwMcvd2qAz5EC5Xa45c,5932
12
+ muapi/commands/auth.py,sha256=brSFzB2UeqW3027wWJC2rSwc-A3arWCfEu6QuQUwo9A,7662
13
+ muapi/commands/config_cmd.py,sha256=QwxP6TFCVNeh1PC-6qXZMvMrAIlHULq8wxL3-Ug9tvo,2606
14
+ muapi/commands/docs.py,sha256=98AIrhdbgMafcUu3f2gJAf1hv-O-XccvqDnHYEB7Kh8,2591
15
+ muapi/commands/edit.py,sha256=YqCSkXf_kWGIPgwoxk0oDFvxT5DH2-GaCX070jcsuso,6381
16
+ muapi/commands/enhance.py,sha256=aolV00gLv805nN-tuN61Y7xxSbHA6_bpQAVbuIeuI0U,7594
17
+ muapi/commands/image.py,sha256=FNTjvFE15MitrzZHKR8RBIQDLMhtcOiVrvFyjiozV1I,12274
18
+ muapi/commands/keys.py,sha256=HLPYmacQsPb-HAmwiHLaqSuaJBxrvyDVqOSS3jOH_qg,3822
19
+ muapi/commands/mcp_server.py,sha256=iYQt5m0moH1b2vHJdbwug-Zg_XgetVkywcFD7dM5RMQ,42367
20
+ muapi/commands/models.py,sha256=zuVDiNKULxmG1jVQ_zxkekStEuIjH8BHecygcJ5gX7M,2651
21
+ muapi/commands/predict.py,sha256=pglGLuDZMYmcF-BnxZkuzGVy0iKJHQuhMDCccSvzxZ4,1724
22
+ muapi/commands/run.py,sha256=bwBW03Ak9Pb40eBf37fMM6BXaAAjvkU2EZ0Mz1Eyhlc,6564
23
+ muapi/commands/upload.py,sha256=Ad5OFkEK1nj6rZF2GFpnvtsuNfDvfiZBg-kyC67Wp7Q,1129
24
+ muapi/commands/video.py,sha256=mPsChrK9xEjCyNxbp27JvM8DxGC2f-7qu3YEi3c8264,13890
25
+ muapi/commands/workflow.py,sha256=WkWwcxfDrc0c3pwuAF81a7C2tyJ02QrvRJFnSoNjKPs,26489
26
+ muapi_cli-0.2.5.dist-info/METADATA,sha256=az52rtwHEIioY8CBJNBC9YQ1QoptuNfBkkqz8pWet04,11686
27
+ muapi_cli-0.2.5.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
28
+ muapi_cli-0.2.5.dist-info/entry_points.txt,sha256=u2r9odPX_uLFWhp_OERiOUsi16aU3M42KS7RoK5JNfw,49
29
+ muapi_cli-0.2.5.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ muapi = muapi.main:_entrypoint