Python SDK
The Musher Python SDK lets you pull bundles, inspect manifests, and access typed assets from Python applications. It provides both synchronous and asynchronous clients with Pydantic-validated responses.
Prerequisites
- Python 3.13 or later
- A Musher API key — create one in the Console
Installation
Install the package
pip install musher-sdkSet your API key
export MUSHER_API_KEY="msk_..."Authentication
The SDK discovers credentials automatically, checking these sources in order:
MUSHER_API_KEYenvironment variable- OS keyring (
musher/<host>) - Credential file (
~/.local/share/musher/credentials/<host>/api-key) - Programmatic — pass a token directly
To pass a token programmatically:
from musher import Client
client = Client(api_key="msk_...")Pull Your First Bundle
The pull() function downloads a bundle from the registry and returns a Bundle object with typed access to its contents.
from musher import pull
bundle = pull("acme/code-review-kit")
print(bundle.manifest.name)
for asset in bundle.manifest.assets:
print(f"{asset.type}: {asset.path}")Work with Typed Handles
Bundles provide typed handles for each asset category. Each handle gives you structured access to the asset content and metadata.
from musher import pull
bundle = pull("acme/code-review-kit")
# Access skills
for skill in bundle.skills:
print(f"Skill: {skill.name}")
print(skill.content)
# Access prompts
for prompt in bundle.prompts:
print(f"Prompt: {prompt.name}")
print(prompt.content)
# Access all files
for file in bundle.files:
print(f"{file.path} ({file.size} bytes)")Resolve Without Pulling
Use resolve() to inspect a bundle's metadata without downloading its full contents. This
is useful for checking versions, listing assets, or validating a reference.
from musher import resolve
result = resolve("acme/code-review-kit@^1.0")
print(f"Resolved version: {result.version}")
print(f"Asset count: {len(result.assets)}")Sync vs Async
The SDK provides both synchronous and asynchronous clients. Use the async variants in applications
that already use asyncio.
Synchronous
from musher import Client, pull
# Using the convenience function
bundle = pull("acme/code-review-kit")
# Using the client directly
client = Client()
bundle = client.pull("acme/code-review-kit")Asynchronous
from musher import AsyncClient, pull_async
# Using the convenience function
bundle = await pull_async("acme/code-review-kit")
# Using the client directly
client = AsyncClient()
bundle = await client.pull("acme/code-review-kit")Key Exports
| Export | Description |
|---|---|
Client | Synchronous bundle registry client |
AsyncClient | Asynchronous bundle registry client |
pull() / pull_async() | Pull a bundle by reference |
resolve() / resolve_async() | Resolve metadata without downloading |
Bundle | Loaded bundle with typed asset access |
Manifest | Bundle metadata and asset list |
SkillHandle | Typed handle for skill assets |
PromptHandle | Typed handle for prompt assets |
ToolsetHandle | Typed handle for toolset assets |
AgentSpecHandle | Typed handle for agent spec assets |
FileHandle | Typed handle for generic file assets |
MusherConfig | Configuration management |