Metadata-Version: 2.4
Name: metricsfirst
Version: 0.1.0
Summary: MetricsFirst SDK for Python - Analytics for Telegram bots
Project-URL: Homepage, https://metricsfirst.com
Project-URL: Documentation, https://docs.metricsfirst.com/python
Project-URL: Repository, https://github.com/metricsfirst/metricsfirst-python
Project-URL: Changelog, https://github.com/metricsfirst/metricsfirst-python/blob/main/CHANGELOG.md
Author-email: MetricsFirst <support@metricsfirst.com>
License-Expression: MIT
License-File: LICENSE
Keywords: analytics,bot,metrics,metricsfirst,telegram,tracking
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Provides-Extra: aiogram
Requires-Dist: aiogram>=3.0.0; extra == 'aiogram'
Requires-Dist: aiohttp>=3.8.0; extra == 'aiogram'
Provides-Extra: all
Requires-Dist: aiogram>=3.0.0; extra == 'all'
Requires-Dist: aiohttp>=3.8.0; extra == 'all'
Provides-Extra: async
Requires-Dist: aiohttp>=3.8.0; extra == 'async'
Provides-Extra: dev
Requires-Dist: aiohttp>=3.8.0; extra == 'dev'
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.20.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# MetricsFirst Python SDK

Official Python SDK for [MetricsFirst](https://metricsfirst.com) - Analytics for Telegram bots.

## Installation

```bash
# Basic installation (sync only)
pip install metricsfirst

# With async support
pip install metricsfirst[async]

# With aiogram middleware
pip install metricsfirst[aiogram]

# Everything
pip install metricsfirst[all]
```

## Quick Start

### Synchronous Client

```python
from metricsfirst import MetricsFirst, CommandEventData, ServiceEventData

# Initialize
mf = MetricsFirst(
    bot_id="your_bot_id",
    api_key="your_api_key",
)

# Track a command
mf.track_command(CommandEventData(
    user_id=123456789,
    command="/start",
    response_time_ms=150,
))

# Track a service
mf.track_service(ServiceEventData(
    user_id=123456789,
    service_name="image_generation",
    is_free=False,
    price=10,
    currency="USD",
))

# Don't forget to shutdown
mf.shutdown()
```

### Asynchronous Client

```python
import asyncio
from metricsfirst import AsyncMetricsFirst, CommandEventData

async def main():
    # Initialize
    mf = AsyncMetricsFirst(
        bot_id="your_bot_id",
        api_key="your_api_key",
    )
    await mf.start()

    # Track events
    await mf.track_command(CommandEventData(
        user_id=123456789,
        command="/start",
    ))

    # Shutdown
    await mf.shutdown()

asyncio.run(main())
```

### Context Manager

```python
# Sync
with MetricsFirst(bot_id="...", api_key="...") as mf:
    mf.track_command(...)

# Async
async with AsyncMetricsFirst(bot_id="...", api_key="...") as mf:
    await mf.track_command(...)
```

## Aiogram Integration

```python
from aiogram import Bot, Dispatcher, Router
from aiogram.types import Message
from metricsfirst import AsyncMetricsFirst
from metricsfirst.middleware import create_aiogram_middleware

bot = Bot(token="BOT_TOKEN")
dp = Dispatcher()
router = Router()

# Initialize MetricsFirst
mf = AsyncMetricsFirst(bot_id="your_bot_id", api_key="your_api_key")

# Add middleware - automatically tracks all commands and interactions
middleware = create_aiogram_middleware(mf)
router.message.middleware(middleware)
router.callback_query.middleware(middleware)

@router.message(commands=["start"])
async def start_handler(message: Message):
    await message.answer("Hello!")

dp.include_router(router)

async def main():
    await mf.start()
    try:
        await dp.start_polling(bot)
    finally:
        await mf.shutdown()
```

## Using Decorators

```python
from metricsfirst import AsyncMetricsFirst
from metricsfirst.middleware import async_track_command, async_track_service

mf = AsyncMetricsFirst(bot_id="...", api_key="...")

@async_track_command(mf, lambda msg: msg.from_user.id)
async def start_handler(message):
    await message.answer("Hello!")

@async_track_service(mf, "download", lambda msg: msg.from_user.id, is_free=False, price=5)
async def download_handler(message):
    # Your download logic
    pass
```

## Available Events

| Method                             | Description                   |
| ---------------------------------- | ----------------------------- |
| `track_command()`                  | Track bot commands            |
| `track_interaction()`              | Track user interactions       |
| `track_service()`                  | Track services provided       |
| `track_error()`                    | Track errors                  |
| `track_error_from_exception()`     | Track error from exception    |
| `track_purchase_initiated()`       | Track purchase start          |
| `track_purchase_completed()`       | Track successful purchase     |
| `track_purchase_error()`           | Track failed purchase         |
| `track_recurring_charge_success()` | Track subscription charge     |
| `track_recurring_charge_failed()`  | Track failed charge           |
| `identify()`                       | Identify user with properties |

## Configuration

```python
mf = MetricsFirst(
    bot_id="your_bot_id",
    api_key="your_api_key",
    api_url="https://api.metricsfirst.com",  # Custom API URL
    batch_events=True,      # Batch events before sending
    batch_size=10,          # Events per batch
    batch_interval=5.0,     # Seconds between flushes
    debug=False,            # Enable debug logging
    timeout=10.0,           # HTTP timeout
)
```

## License

MIT
