Metadata-Version: 2.4
Name: tiden-telemetry
Version: 0.1.0
Summary: Error-tracking SDK for Python — captures errors and reports them to a Tiden project.
Project-URL: Homepage, https://tiden.ai
Project-URL: Repository, https://github.com/qase-tms/tiden-telemetry-python
Project-URL: Issues, https://github.com/qase-tms/tiden-telemetry-python/issues
Author: Tiden
License-Expression: MIT
License-File: LICENSE
Keywords: error-tracking,exceptions,monitoring,observability,telemetry,tiden
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3 :: Only
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: Topic :: Software Development :: Bug Tracking
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# tiden-telemetry (Python)

[![CI](https://github.com/qase-tms/tiden-telemetry-python/actions/workflows/ci.yml/badge.svg)](https://github.com/qase-tms/tiden-telemetry-python/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/tiden-telemetry)](https://pypi.org/project/tiden-telemetry/)
[![Python](https://img.shields.io/pypi/pyversions/tiden-telemetry)](https://pypi.org/project/tiden-telemetry/)

Error-tracking SDK for **Python** apps. Captures errors and uncaught exceptions
and reports them to your [Tiden](https://tiden.ai) project, with WSGI middleware
and a `logging` handler. **Zero dependencies** (standard library only), typed.

## Install

```bash
pip install tiden-telemetry
```

## Quick start

```python
import tiden_telemetry as tiden

tiden.init(
    dsn="http://<publicKey>@<host:ingestPort>/<projectId>",
    release="my-app@1.2.3",
    environment="production",
)

try:
    do_work()
except Exception:
    tiden.capture_exception()  # inside an except block, no argument needed
```

`init` installs `sys.excepthook` / `threading.excepthook`, so uncaught
exceptions are reported automatically.

## Capturing

```python
tiden.capture_exception(err)
tiden.capture_message("checkout completed", "info")

tiden.set_tag("plan", "pro")
tiden.set_user({"id": "u_123"})
```

## WSGI middleware

Captures unhandled exceptions in your app, then re-raises (so the server's own
error handling still runs):

```python
from tiden_telemetry.wsgi import TidenWsgiMiddleware

application = TidenWsgiMiddleware(application)
```

The captured event includes request URL, method, and headers (sensitive headers
are scrubbed unless `send_default_pii` is set).

## logging handler

Route records (≥ `ERROR` by default) through Tiden — `logger.exception(...)`
becomes a captured exception:

```python
import logging
from tiden_telemetry.logging import TidenLoggingHandler

logging.getLogger().addHandler(TidenLoggingHandler())
```

## Options

`tiden.init(...)` / `tiden.Client(...)`:

| Option | Type | Default | Description |
|---|---|---|---|
| `dsn` | `str` | — | **Required.** `http://<publicKey>@<host:ingestPort>/<projectId>`. |
| `release` | `str` | `None` | App version, e.g. `my-app@1.2.3`. |
| `environment` | `str` | `None` | e.g. `production`, `staging`. |
| `send_default_pii` | `bool` | `False` | Send likely-PII. Off by default — common PII is scrubbed. |
| `before_send` | `Callable[[dict], dict \| None]` | `None` | Inspect, mutate, or drop an event. Return `None` to drop. |
| `http_timeout` | `float` | `2.0` | Bounds each synchronous send (seconds). |
| `install_excepthook` | `bool` | `True` (`init`) | Install global excepthooks. |

Use `tiden.Client(...)` directly for multiple clients or to avoid global state;
pass it to `TidenWsgiMiddleware(app, client=...)` / `TidenLoggingHandler(client=...)`.

## How it works

- Parses the DSN to `/api/<projectId>/envelope/?tiden_key=…`.
- Normalizes exceptions (incl. the `__cause__` / `__context__` chain) into
  `exception.values[]` with stack frames (`in_app` excludes the stdlib and
  site-packages).
- Serializes the envelope and POSTs it with `Content-Type:
  application/x-tiden-envelope` — **synchronous, never raises into the host**;
  honors HTTP 429 + `Retry-After`.
- Scrubs likely-PII (auth headers, secret-ish keys) unless `send_default_pii`.

## Develop

```bash
pip install -e ".[dev]"
ruff check . && ruff format --check .
mypy
pytest -q
```

## License

[MIT](LICENSE) © Tiden
