Metadata-Version: 2.5
Name: auditlogs
Version: 0.0.1
Summary: AuditLogs Python SDK - tamper-evident audit trail client
Project-URL: Homepage, https://github.com/jamesadewara/auditlogs-python-package
Project-URL: Bug Tracker, https://github.com/jamesadewara/auditlogs-python-package/issues
Author-email: James Adewara <jamesadewara1@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: audit,compliance,logging,observability,security,tamper-evident
Classifier: Development Status :: 3 - Alpha
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: Topic :: Security
Classifier: Topic :: System :: Logging
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27.0
Requires-Dist: tenacity>=8.0.0
Provides-Extra: dev
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# AuditLogs Python SDK

A lightweight, robust Python client for the **AuditLogs** tamper-evident auditing platform.

This SDK allows your Python applications to seamlessly ingest audit events into AuditLogs, ensuring cryptographically verifiable, non-repudiable audit trails.

## Installation

```bash
pip install auditlogs
# (Note: Package will be published under your desired PyPI name)
```

## Quick Start

```python
from auditlogs import AuditLogsClient, Actor, AuditEvent
from datetime import datetime, timezone

# Initialize the client with your write key
client = AuditLogsClient(
    api_key="aud_w_your_write_key_here",
    slug="billing-events",  # The audit trail slug
    base_url="https://api.auditlogs.io"  # Omit to use default
)

# Create and ingest an event
event = AuditEvent(
    actor=Actor(
        type="user", 
        id="usr_abc123", 
        ip="192.168.1.55"
    ),
    action="invoice.paid",
    outcome="success",
    summary="Invoice INV-2023-001 was paid successfully",
    resource_type="invoice",
    resource_id="INV-2023-001",
    metadata={
        "amount": 4999,
        "currency": "USD",
        "payment_method": "card"
    }
)

# Synchronous ingest
result = client.ingest(event)
print(f"Ingested! Sequence: {result.seq}, Event ID: {result.id}")

# Or use fire-and-forget for non-blocking ingestion
client.fire_and_forget(event)

# Always close the client (or use a context manager)
client.close()
```

## Context Manager

The client supports context managers to ensure resources (and background threads) are cleaned up automatically:

```python
with AuditLogsClient(api_key="aud_w_...", slug="billing") as client:
    client.ingest(event)
```

## Asynchronous Support

For `asyncio` applications (e.g., FastAPI, Starlette, AIOHTTP), use the `AsyncAuditLogsClient`:

```python
import asyncio
from auditlogs import AsyncAuditLogsClient, Actor, AuditEvent

async def main():
    async with AsyncAuditLogsClient(api_key="aud_w_...", slug="billing") as client:
        result = await client.ingest(
            AuditEvent(
                actor=Actor(type="system", id="cron-job"),
                action="monthly.billing.run",
                outcome="success"
            )
        )
        print(f"Ingested event seq: {result.seq}")

asyncio.run(main())
```

## Event Retrieval

You can fetch events back from the trail using a **Read Key** (`aud_r_...`):

```python
read_client = AuditLogsClient(api_key="aud_r_...", slug="billing-events")

# Paginated list
page = read_client.list(page=1, page_size=50, action="invoice.paid")
for item in page.items:
    print(item["summary"])

# Fetch single event by sequence
event_data = read_client.get(sequence=42)

# Verify chain integrity cryptographically
report = read_client.verify()
if report.chain_valid:
    print("Chain is intact!")
else:
    print(f"Chain corrupted at sequence {report.corrupted_at_sequence}")

# Export all data as CSV
csv_bytes = read_client.export_csv()
with open("export.csv", "wb") as f:
    f.write(csv_bytes)
```

## Fire and Forget

If you don't want to block your application's critical path waiting for an HTTP request to the auditing service to complete, use `fire_and_forget`:

```python
# Puts the event in a background queue and returns immediately
client.fire_and_forget(event)
```
*Note: Events dropped due to network issues using `fire_and_forget` are not retried indefinitely. For critical compliance logs where drop-rate must be 0%, use `ingest()`.*

## Development

Install dependencies:
```bash
pip install -e ".[dev]"
```

Run tests:
```bash
pytest tests/ -v
```