Skip to main content

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

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

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