Skip to main content

PyPlanhat SDK

Modern async-first Python SDK for the Planhat API.

Features

  • 🚀 Async-first architecture with auto-generated sync support
  • 📦 Built with modern Python tooling (httpx, pydantic, uv)
  • 🔒 Type-safe with full mypy support
  • ✨ Comprehensive error handling with custom exception hierarchy
  • 🧪 Extensively tested with 97% coverage
  • 📚 Complete resource coverage - Companies, EndUsers, Conversations
  • 🎨 Fully extensible models - Subclass and add your own typed fields

Installation

pip install pyplanhat

Quick Start

Async Usage (Recommended)

import asyncio
from pyplanhat import AsyncPyPlanhat, Company

async def main():
    async with AsyncPyPlanhat(api_key="your-api-key") as client:
        # List all companies
        companies = await client.companies.list()

        # Get a specific company
        company = await client.companies.get("company-id")

        # Create a new company
        new_company = Company(
            name="Acme Corporation",
            status="prospect",
            custom={"industry": "Technology"}
        )
        created = await client.companies.create(new_company)

        # Work with end users
        users = await client.endusers.list(company_id=company.id)

        # Work with conversations
        conversations = await client.conversations.list(company_id=company.id)

asyncio.run(main())

Sync Usage

from pyplanhat import PyPlanhat, Company

with PyPlanhat(api_key="your-api-key") as client:
    # All the same methods work synchronously
    companies = client.companies.list()
    company = client.companies.get("company-id")

For detailed examples and advanced usage, see USAGE.md.

Configuration

Set environment variables for convenient testing:

export PLANHAT_API_KEY="your-api-key"
export PLANHAT_API_BASE_URL="https://api.planhat.com"  # optional

Or pass directly to the client:

client = AsyncPyPlanhat(
    api_key="your-api-key",
    base_url="https://api.planhat.com"
)

Resources

PyPlanhat provides complete CRUD operations for the following Planhat resources:

  • Companies - Manage customer companies with full lifecycle tracking
  • EndUsers - Manage contacts and end users within companies
  • Conversations - Track interactions, meetings, and communications

Each resource supports:

  • list() - Get all resources (with optional filtering)
  • get(id) - Get a specific resource by ID
  • create(resource) - Create a new resource
  • update(id, resource) - Update an existing resource
  • delete(id) - Delete a resource

Development

Setup

# Clone repository
git clone https://github.com/ddlaws0n/pyplanhat.git
cd pyplanhat

# Install dependencies
uv sync --all-groups

# Run tests
uv run pytest -v

# Format code
uv run ruff format .

# Lint code
uv run ruff check .

# Type check
uv run mypy src/

Architecture

PyPlanhat uses an async-first DRY architecture:

  1. ✏️ Write async code in src/pyplanhat/_async/
  2. 🔄 Generate sync code: python scripts/generate_sync.py
  3. ✅ Both versions tested identically
  4. 📦 Zero duplication of business logic

The synchronous version is automatically generated from the async source using unasync, ensuring perfect parity between both APIs.

Development Guidelines

See CLAUDE.md for detailed development guidelines and workflow.

Key principles:

  • Never edit files in _sync/ directories (they're auto-generated)
  • Always run python scripts/generate_sync.py after modifying async code
  • Maintain test parity between async and sync test suites
  • Follow the phased plan in docs/pyplanhat/PLAN.md

Project Structure

src/pyplanhat/
├── _async/              # Async source code (write here)
│   ├── client.py        # Main async client
│   └── resources/       # Async resource implementations
├── _sync/               # Generated sync code (never edit)
│   ├── client.py        # Generated sync client
│   └── resources/       # Generated sync resources
├── _exceptions.py       # Custom exception hierarchy
└── __init__.py         # Public API exports

tests/
├── _async/             # Async tests (write here)
└── _sync/              # Generated sync tests (never edit)

Roadmap

  • Phase 0: Foundation (exception hierarchy, client shell, code generation) ✅ Complete
  • Phase 1: Companies resource implementation ✅ Complete
  • Phase 2: EndUsers and Conversations resources ✅ Complete
  • Phase 3: Documentation (mkdocs, API reference) 🚧 In Progress
  • Phase 4: Release to PyPI ✅ Complete (v0.1.0 published)

Contributing

This project follows strict architectural patterns and phased development. Please review:

  1. CLAUDE.md - Development workflow and commands
  2. docs/pyplanhat/PLAN.md - Phased development plan
  3. docs/pyplanhat/ARCHITECTURE.md - Architecture details

License

MIT License - see LICENSE for details.

Support

For issues, questions, or contributions, please open an issue on GitHub.

Metadata

Release files for pyplanhat 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyplanhat 0.2.1
File Size Uploaded
pyplanhat-0.2.1.tar.gz 162.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyplanhat 0.2.1
File Interpreter ABI Platform
pyplanhat-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 184.0 kB

Release files / pyplanhat-0.2.1.tar.gz

Download URL pyplanhat-0.2.1.tar.gz
Size 162.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5fbe214d62668f92302d88683cdd8c10c4379c9c9a3dc3e2af80c749a59761fd
BLAKE2b-256 checksum
How to use checksums
8687b7cfd5d17d9e58f01a7c8d8c2fdceceb5c4d293e7b657329bc88e48c114f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2025.

Transparency log

Release files / pyplanhat-0.2.1-py3-none-any.whl

Download URL pyplanhat-0.2.1-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e62d6d74478da09c35a97bb0bb5c17f4069c5d6dbed0a03188bdd3b66e5cdc48
BLAKE2b-256 checksum
How to use checksums
784ec43226379e74726c3f06dca8bd20988befe9a40a6dacd8bc68e0fa2928da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page