Python 88.3%
TypeScript 7.6%
Shell 4.1%
1#!/usr/bin/env python32"""Skills API lifecycle + one Messages call using an Anthropic skill (official Python SDK).34STATUS: LIVE_VERIFIED 2026-09-18 for the HTTP sequence (executed via scripts/live.py: list/create/retrieve/versions/5download/delete, and POST /v1/messages with container.skills + code_execution → 200, ~8.3k input tokens ≈ $0.009).6The SDK calls below map 1:1 (client.skills.*, client.skills.versions.*). Skills API is GA — no beta header.7Run: .venv/bin/python examples/anthropic/skills/skills_lifecycle.py [--messages] (--messages adds the ~$0.01 call)8"""9from __future__ import annotations10import io, sys11from pathlib import Path1213ROOT = Path(__file__).resolve().parents[3]14sys.path.insert(0, str(ROOT))15from scripts.live import load_env, log_request # noqa: E4021617load_env()18import anthropic # noqa: E4021920client = anthropic.Anthropic()2122# 1. Anthropic skills23for s in client.skills.list(source="anthropic"):24 print("anthropic skill:", s.id, s.display_name, s.latest_version_id)25log_request("anthropic", "GET", "/v1/skills", 200, 0, "sdk skills list anthropic")2627# 2. create a custom skill (files must include SKILL.md with YAML frontmatter name + description)28skill_md = ("---\nname: atlas-platform-agent-demo\ndescription: Tiny demo skill created by the API Atlas example; "29 "says OK when asked for a status check.\n---\n# Atlas demo skill\nWhen asked for a status check, reply with exactly `OK`.\n")30files = [("atlas-platform-agent-demo/SKILL.md", io.BytesIO(skill_md.encode()), "text/markdown")]31skill = client.skills.create(files=files, display_name="atlas-platform-agent-demo")32log_request("anthropic", "POST", "/v1/skills", 200, 0, "sdk skills create")33print("created", skill.id, skill.source.type, skill.latest_version_id)3435# 3. retrieve / versions / latest / download36print("retrieve", client.skills.retrieve(skill.id).display_name)37print("versions", [v.id for v in client.skills.versions.list(skill_id=skill.id)])38latest = client.skills.versions.retrieve("latest", skill_id=skill.id)39print("latest", latest.id, latest.name)40# download (beta reference endpoint GET /v1/skills/{id}/versions/{v}/content → zip)41content = client.beta.skills.versions.download(latest.id, skill_id=skill.id)42print("download zip bytes:", len(content.read()) if hasattr(content, "read") else content)4344# 4. second version, then delete it (deleting the ONLY version → 400)45v2 = client.skills.versions.create(skill_id=skill.id, files=[46 ("atlas-platform-agent-demo/SKILL.md", io.BytesIO(skill_md.replace("`OK`", "`OK` (v2)").encode()), "text/markdown"),47 ("atlas-platform-agent-demo/notes.md", io.BytesIO(b"# notes\n"), "text/markdown")])48print("v2", v2.id, "deleted:", client.skills.versions.delete(v2.id, skill_id=skill.id).type)4950# 5. cleanup: delete skill (removes all versions)51print("delete skill:", client.skills.delete(skill.id).type)52log_request("anthropic", "DELETE", "/v1/skills/{id}", 200, 0, "sdk skills delete")5354# 6. optional: use the Anthropic `xlsx` skill in a Messages call (needs code execution; ~$0.01 on Haiku 4.5)55if "--messages" in sys.argv:56 msg = client.beta.messages.create(57 model="claude-haiku-4-5-20251001", max_tokens=200,58 betas=["code-execution-2025-08-25"],59 container={"skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]},60 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],61 messages=[{"role": "user", "content": "Do not run code or create files. In one sentence, what does the loaded skill help with? Then reply OK."}],62 )63 log_request("anthropic", "POST", "/v1/messages", 200, 0.01, "sdk messages with container.skills xlsx")64 print([b.type for b in msg.content], msg.usage.input_tokens, msg.usage.output_tokens)65