Skip to main content

Python client library for Workshop Cloud API

Project description

workshop-client

Python client library for Workshop Cloud API

Clean, type-safe Python interface to Workshop Cloud - persistent context and memory for Claude Code.

Features

  • Type-safe: Full Pydantic models for all API entities
  • Mock backend: Develop and test without real API
  • Async-ready: Built on httpx (async support coming soon)
  • Well-tested: Comprehensive test coverage
  • Python 3.8+: Wide compatibility

Installation

pip install workshop-client

For E2EE (zero-knowledge encryption) support:

pip install workshop-client[crypto]

Quick Start

Using Mock Backend (No API Required)

Perfect for development and testing:

from workshop_client import WorkshopClient

# Mock mode - no network requests
client = WorkshopClient(api_key="wks_mock", mock=True)

# Create a project
project = client.create_project(
    name="my-app",
    display_name="My App",
    description="Mobile app project"
)

# Add entries
client.create_entry(
    project="my-app",
    type="decision",
    content="Use PostgreSQL for database",
    reasoning="Better ACID guarantees",
    tags=["database", "architecture"]
)

client.create_entry(
    project="my-app",
    type="gotcha",
    content="API rate limit is 300 req/min",
    tags=["api", "performance"]
)

# Search
results = client.search("my-app", "PostgreSQL")
print(f"Found {results.total} results")

# Smart 'why' query (prioritizes decisions)
why = client.why("my-app", "PostgreSQL")
if why.primary_answer:
    print(f"Why PostgreSQL? {why.primary_answer.reasoning}")

# Get context summary
context = client.get_context("my-app")
print(f"Goals: {len(context.active_goals)}")
print(f"Next steps: {len(context.next_steps)}")

Using Real API

from workshop_client import WorkshopClient

# Real API mode
client = WorkshopClient(api_key="wks_your_api_key_here")

# Same API as mock mode
project = client.create_project(...)
entry = client.create_entry(...)

API Overview

Projects

# List all projects
projects = client.list_projects()

# Get project details
project = client.get_project("my-app")

# Create project
project = client.create_project(
    name="my-app",
    display_name="My App",
    description="Optional description"
)

# Update project
project = client.update_project(
    "my-app",
    display_name="My Awesome App"
)

# Delete project
result = client.delete_project("my-app")

Entries

from workshop_client import EntryType

# Create entry
entry = client.create_entry(
    project="my-app",
    type=EntryType.NOTE,  # or "note"
    content="Important note",
    tags=["tag1", "tag2"]
)

# Create decision with reasoning
entry = client.create_entry(
    project="my-app",
    type=EntryType.DECISION,
    content="Use FastAPI for backend",
    reasoning="Better async support and auto-docs",
    tags=["backend"]
)

# List entries
entries = client.list_entries("my-app")

# Filter by type
decisions = client.list_entries("my-app", type=EntryType.DECISION)

# Filter by tags
tagged = client.list_entries("my-app", tags=["backend", "api"])

# Get specific entry
entry = client.get_entry("my-app", entry_id)

# Update entry
updated = client.update_entry(
    "my-app",
    entry_id,
    content="Updated content",
    tags=["new-tag"]
)

# Delete entry
result = client.delete_entry("my-app", entry_id)

Search & Context

# Full-text search
results = client.search(
    "my-app",
    query="authentication",
    type=EntryType.DECISION,
    limit=10
)

for result in results.results:
    print(f"[{result.score:.2f}] {result.content}")

# Smart 'why' query (prioritizes decisions with reasoning)
why = client.why("my-app", "JWT")
if why.primary_answer:
    print(f"Decision: {why.primary_answer.content}")
    print(f"Reasoning: {why.primary_answer.reasoning}")

# Get context summary
context = client.get_context("my-app", days=30)
print(f"Last activity: {context.last_activity}")
print(f"Summary: {context.summary}")
print(f"Active goals: {len(context.active_goals)}")

User

# Get current user
user = client.get_user()
print(f"Email: {user.email}")
print(f"Tier: {user.subscription['tier']}")
print(f"API calls today: {user.usage['api_calls_today']}")

# Update user
user = client.update_user(
    name="John Doe",
    preferences={"timezone": "America/Los_Angeles"}
)

# Get audit log
audit = client.get_audit_log()
for log in audit.logs:
    print(f"{log.timestamp}: {log.action} {log.resource}")

Entry Types

from workshop_client import EntryType

EntryType.NOTE          # General notes
EntryType.DECISION      # Architectural decisions (use with reasoning)
EntryType.GOTCHA        # Constraints, limitations, things to avoid
EntryType.PREFERENCE    # User/team preferences
EntryType.ANTIPATTERN   # Patterns to avoid
EntryType.GOAL          # Active goals
EntryType.NEXT          # Next steps, TODOs

Error Handling

from workshop_client import (
    WorkshopClient,
    AuthenticationError,
    NotFoundError,
    ValidationError,
    RateLimitError,
)

client = WorkshopClient(api_key="wks_...")

try:
    entry = client.create_entry("my-app", "note", "Content")
except AuthenticationError:
    print("Invalid API key")
except NotFoundError as e:
    print(f"Not found: {e.message}")
except ValidationError as e:
    print(f"Invalid input: {e.details}")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.details['retry_after']}s")

Context Manager

with WorkshopClient(api_key="wks_...") as client:
    projects = client.list_projects()
    # Client automatically closes on exit

Development

Run Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# With coverage
pytest --cov=workshop_client --cov-report=term-missing

Mock Backend

The mock backend provides realistic API responses without requiring a real backend:

  • In-memory storage (resets on restart)
  • Pre-populated sample project with entries
  • Full API support (projects, entries, search, context)
  • Perfect for testing and development
client = WorkshopClient(api_key="anything", mock=True)
# All API calls work, but use in-memory storage

Roadmap

  • E2EE (zero-knowledge encryption) support
  • Async client (AsyncWorkshopClient)
  • Batch operations
  • Webhooks support
  • Team management APIs

Links

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please open an issue or PR on GitHub.


Built with ❤️ for the Workshop Cloud community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

workshop_client-0.1.0.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

workshop_client-0.1.0-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file workshop_client-0.1.0.tar.gz.

File metadata

  • Download URL: workshop_client-0.1.0.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for workshop_client-0.1.0.tar.gz
Algorithm Hash digest
SHA256 49131c7b82a4ebebd139c51ffaaac14b5d00f7083aef0ff31a2066ad15356cca
MD5 65a2fa4134823482cb18d9b246070aae
BLAKE2b-256 ee779537684c459b9cef662d0ec01a5fc0177b27e3c420f23841c36bf830c0a7

See more details on using hashes here.

File details

Details for the file workshop_client-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for workshop_client-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c86bc553afe59f866271b843d0c7f80a8d83b99daf25fdc516c40f163370f5b2
MD5 fbb451fab4b0bcfd6b80a6b8f29fe631
BLAKE2b-256 7530934a484dd784c355a5bae1c77f310471bb8f20f328762cdd0eb6e007dc5f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page