Metadata-Version: 2.4
Name: piano-analytics-client
Version: 1.0.0
Summary: Python SDK for Piano Analytics data collection
Project-URL: Homepage, https://github.com/MCPAppsBuilders/piano-analytics-client
Project-URL: Repository, https://github.com/MCPAppsBuilders/piano-analytics-client.git
Project-URL: Documentation, https://github.com/MCPAppsBuilders/piano-analytics-client#readme
Author: MCP Apps Builders
License: MIT
Keywords: analytics,piano,sdk,tracking
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pyright>=1.1.390; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.32.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Description-Content-Type: text/markdown

# Piano Analytics Python Client

A Python SDK for sending analytics events to [Piano Analytics](https://piano.io/product/analytics/).

## Installation

```bash
uv add piano-analytics-client
```

Or with pip:

```bash
pip install piano-analytics-client
```

## Quick Start

### Synchronous Usage

```python
from piano_analytics import PianoAnalytics

# Initialize the client
pa = PianoAnalytics(
    site_id=123456789,
    collect_domain="https://your-domain.pa-cd.com"
)

# Send a page view event
pa.send_event("page.display", {
    "page": "homepage",
    "page_chapter1": "home"
})

# Send a click event
pa.send_event("click.action", {
    "click": "signup_button",
    "click_chapter1": "header"
})

# Close the client when done
pa.close()
```

### Using Context Manager (Recommended)

```python
from piano_analytics import PianoAnalytics

with PianoAnalytics(site_id=123456789, collect_domain="https://...") as pa:
    pa.send_event("page.display", {"page": "checkout"})
```

### Asynchronous Usage

```python
import asyncio
from piano_analytics import AsyncPianoAnalytics

async def main():
    async with AsyncPianoAnalytics(
        site_id=123456789,
        collect_domain="https://your-domain.pa-cd.com"
    ) as pa:
        # Send events asynchronously
        await pa.send_event("page.display", {"page": "product_page"})

        # Send multiple events concurrently
        await asyncio.gather(
            pa.send_event("click.action", {"click": "add_to_cart"}),
            pa.send_event("click.action", {"click": "view_details"})
        )

asyncio.run(main())
```

## Configuration Options

```python
from piano_analytics import PianoAnalytics

pa = PianoAnalytics(
    site_id=123456789,                    # Required: Your site ID
    collect_domain="https://...",          # Required: Collection endpoint
    visitor_id="custom-uuid",              # Optional: Custom visitor ID (auto-generated if not provided)
    timeout=30.0,                          # Optional: Request timeout in seconds (default: 10)
    max_retries=5,                         # Optional: Retry attempts (default: 3)
    user_agent="MyApp/1.0"                 # Optional: Custom User-Agent
)
```

## Using Event Helpers

The SDK provides convenient factory methods for standard events:

```python
from piano_analytics import PianoAnalytics
from piano_analytics.events import Event

with PianoAnalytics(site_id=123, collect_domain="https://...") as pa:
    # Using factory methods
    events = [
        Event.page_display("homepage", page_chapter1="home"),
        Event.click_action("signup", click_chapter1="header"),
        Event.search_display(ise_keyword="python", ise_page=1),
    ]
    pa.send_events(events)
```

## Batch Sending

Send multiple events in a single request:

```python
pa.send_events([
    {"name": "page.display", "data": {"page": "home"}},
    {"name": "click.action", "data": {"click": "menu"}},
    {"name": "click.navigation", "data": {"click": "products"}}
])
```

## Error Handling

```python
from piano_analytics import PianoAnalytics
from piano_analytics.exceptions import (
    ValidationError,
    NetworkError,
    APIError
)

with PianoAnalytics(site_id=123, collect_domain="https://...") as pa:
    try:
        pa.send_event("page.display", {"page": "home"})
    except ValidationError as e:
        print(f"Invalid event data: {e}")
    except NetworkError as e:
        print(f"Network issue: {e}")
    except APIError as e:
        print(f"API error: {e.status_code} - {e.message}")
```

## Standard Events

| Event | Description |
|-------|-------------|
| `page.display` | Track page views |
| `click.action` | Track user interactions |
| `click.navigation` | Track navigation clicks |
| `click.download` | Track file downloads |
| `click.exit` | Track exit links |
| `internal_search_result.display` | Track search results |
| `internal_search_result.click` | Track search result clicks |

## Development

```bash
# Install dependencies
uv sync --all-extras

# Run tests
uv run pytest

# Run linting
uv run ruff check .

# Run type checking
uv run pyright
```

## License

MIT
