Skip to content
AI/LLM: This documentation page is available in plain markdown format at /docs/sdk-python.md

Python SDK

tankpkg gives your Python application programmatic access to the Tank skill registry. Search skills, read their full content (including references and scripts), download tarballs with integrity verification, and inspect security audit results — with typed exceptions, streaming downloads, and context manager support.

DISCOVERY search("react") → 47 skills found name, score, downloads, version CONTENT read_skill("@tank/react") → SKILL.md + references/ + scripts/ full content for LLM context INTEGRITY download("@tank/react") → SHA-512 verified .tar.gz 100MB cap, streaming download SECURITY audit("@tank/react") → score: 9.2, verdict: PASS 6-stage scan findings TankClient — same API as the TypeScript SDK Auto-discovers token from ~/.tank/config.json → TANK_TOKEN env → explicit token= parameter
pip install tankpkg

Quick Start

from tankpkg import TankClient

with TankClient() as client:
    # Search for skills
    results = client.search("react")
    print(f"{results['total']} skills found")

    # Read a skill's full content (SKILL.md + references + scripts)
    skill = client.read_skill("@tank/react")
    print(skill.content)          # SKILL.md text
    print(skill.references)       # {'hooks.md': '...', 'performance.md': '...'}
    print(skill.scripts)          # {'setup.sh': '...'}

    # Feed to an LLM as system context
    system_prompt = "\n".join([
        skill.content,
        *[f"--- {name} ---\n{text}" for name, text in skill.references.items()]
    ])

Constructor

client = TankClient(**options)
ParameterTypeDefaultDescription
tokenstr | Noneauto-discoveredAPI key. If omitted, reads ~/.tank/config.json then TANK_TOKEN env.
registry_urlstr | Nonehttps://www.tankpkg.devRegistry URL. Set for self-hosted/on-prem instances. http:// allowed.
config_dirstr | None~/.tankDirectory containing config.json.
max_retriesint3Retry count for 429 and 5xx responses (exponential backoff).
timeoutfloat30.0HTTP request timeout in seconds.

Auth discovery order: explicit token > TANK_TOKEN env > ~/.tank/config.json

# Explicit token (CI/server)
client = TankClient(token="tank_xxx")

# Self-hosted
client = TankClient(registry_url="http://tank.internal:5555")

# Zero-config (uses CLI auth)
client = TankClient()

Context Manager

TankClient supports with statements. The underlying httpx.Client is closed automatically on exit:

with TankClient() as client:
    skill = client.read_skill("@tank/react")
    # httpx client closed automatically here

Without with, call client.close() explicitly when done.


Skill Content

The most important methods for AI agent integrations. These let you load a skill's full content — SKILL.md plus all reference files and scripts — for use as LLM context.

read_skill(name, version=None)

Loads the complete skill content in a single call.

skill = client.read_skill("@tank/react")

Returns: SkillContent dataclass

FieldTypeDescription
namestrSkill name
versionstrResolved version
contentstrSKILL.md text
referencesdict[str, str]Reference files keyed by filename
scriptsdict[str, str]Script files keyed by filename
fileslist[str]All file paths in the package

list_files(name, version=None)

Lists all files in a skill package.

files = client.list_files("@tank/react")
# ['SKILL.md', 'references/hooks.md', 'references/performance.md', 'scripts/setup.sh', 'skills.json']

read_file(name, version, file_path)

Reads a single file from a skill package.

content = client.read_file("@tank/react", "2.2.0", "references/hooks.md")

Path traversal (..), absolute paths, and null bytes are rejected with TankNetworkError.


Discovery

search(query, *, page=1, limit=20)

results = client.search("typescript", page=1, limit=10)
for skill in results["results"]:
    print(skill["name"], skill["description"])

info(name)

info = client.info("@tank/react")
print(info["latestVersion"])  # '2.2.0'
print(info["downloads"])      # 1234

versions(name)

result = client.versions("@tank/react")
for v in result["versions"]:
    print(v["version"], v["auditScore"], v["publishedAt"])

Download

download(name, version, *, dest=None)

Downloads a skill tarball. Always returns the raw bytes. If dest is provided, also writes to disk.

# Buffer only — returns bytes, integrity verified
data = client.download("@tank/react", "2.2.0")

# Write to disk — also returns bytes
data = client.download("@tank/react", "2.2.0", dest="./skills/")

SHA-512 integrity is always verified against the registry hash. Download size is capped at 100MB with streaming enforcement.


Security & Audit

audit(name, version=None)

Returns the full security analysis as a VersionDetail dataclass.

result = client.audit("@tank/react")
print(result.audit_score)     # 9.5
print(result.scan_findings)   # [{'stage': 'static', 'severity': 'low', ...}]

permissions(name, version=None)

perms = client.permissions("@tank/react")
# {'network': {'outbound': ['*.api.com']}, 'filesystem': {'read': ['./data/**']}, 'subprocess': False}

Auth

whoami()

Returns UserInfo if authenticated, None otherwise.

user = client.whoami()
if user:
    print(user.user_id, user.name, user.email)

Stars

# Get star count
stars = client.get_star_count("@tank/react")
print(stars["count"], stars["isStarred"])

# Star/unstar (requires session auth)
client.star("@tank/react")
client.unstar("@tank/react")

Error Handling

All errors extend TankError. Catch specific types for programmatic handling:

from tankpkg import TankClient, TankNotFoundError, TankAuthError

try:
    client.info("@acme/missing")
except TankNotFoundError as e:
    print(e.status)       # 404
    print(e.skill_name)   # '@acme/missing'
except TankAuthError:
    print("Invalid token")
ExceptionHTTP StatusWhen
TankAuthError401Invalid or missing token
TankNotFoundError404Skill or file not found
TankPermissionError403Insufficient permissions
TankNetworkErrorConnection failure, timeout, redirect
TankIntegrityErrorSHA-512 hash mismatch
TankConflictError409Dependency resolution conflict

Full Example: Load Skill into OpenAI

from tankpkg import TankClient
from openai import OpenAI

tank = TankClient()
openai = OpenAI()

# 1. Load skill with all references
skill = tank.read_skill("@tank/react")

# 2. Build system prompt
parts = [skill.content]
for name, text in skill.references.items():
    parts.append(f"\n--- Reference: {name} ---\n{text}")
system_prompt = "\n".join(parts)

# 3. Use as LLM context
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": "How should I handle data fetching in React?"},
    ],
)

Types

from tankpkg import (
    TankClient,
    SkillContent,       # dataclass: name, version, content, references, scripts, files
    UserInfo,           # dataclass: user_id, name, email
    VersionDetail,      # dataclass: name, version, integrity, audit_score, ...
    TankError,
    TankAuthError,
    TankNotFoundError,
    TankPermissionError,
    TankNetworkError,
    TankIntegrityError,
    TankConflictError,
)

Differences from TypeScript SDK

FeatureTypeScriptPython
Installnpm install @tankpkg/sdkpip install tankpkg
NamingcamelCasesnake_case
Client cleanupGarbage collectedwith statement or .close()
Download defaultReturns ReadableStreamReturns bytes
File read batchingConcurrent (6 at a time)Sequential
Install pipelineAvailable (extracted from CLI)Not yet available
Native accelerationOptional Rust core via NAPI-RSFuture via PyO3

Command Palette

Search skills, docs, and navigate Tank