Metadata-Version: 2.4
Name: boringapi
Version: 0.1.0
Summary: Python SDK for the Boring API — U.S. building permit data
Project-URL: Homepage, https://boringapi.dev
Project-URL: Documentation, https://boringapi.dev/docs
Project-URL: Repository, https://github.com/boringapi/boring-python
Author-email: Boring API <hello@boringapi.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: api,building-permits,construction,government-data,permits,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Description-Content-Type: text/markdown

# boringapi

Python SDK for the [Boring API](https://boringapi.dev) — U.S. building permit data. One API.

```
pip install boringapi
```

## Quick start

```python
from boringapi import BoringAPI

client = BoringAPI("bp_live_sk_...")

# List permits
permits = client.permits.list(state="CA", limit=10)
for permit in permits.data:
    print(permit.id, permit.status, permit.address.full)

# Get a single permit
permit = client.permits.get("pmt_abc123")

# Search
results = client.permits.search("solar panel installation")

# Nearby permits
nearby = client.permits.nearby(latitude=37.7749, longitude=-122.4194, radius_miles=0.5)

# Bulk fetch
permits = client.permits.bulk(["pmt_abc123", "pmt_def456"])

client.close()
```

## Auto-pagination

Iterate through all results automatically:

```python
for permit in client.permits.auto_paging_iter(state="CA", status="issued"):
    print(permit.permit_number)
```

## Jurisdictions

```python
jurisdictions = client.jurisdictions.list(state="CA")
jurisdiction = client.jurisdictions.get("jur_san_francisco")
```

## Account

```python
account = client.accounts.me()
usage = client.accounts.usage()
```

## API keys

```python
keys = client.keys.list()
new_key = client.keys.create(name="CI Pipeline")
print(new_key.key)  # Only shown once
client.keys.revoke("key_abc123")
```

## Webhooks

```python
webhook = client.webhooks.create(
    url="https://example.com/webhook",
    events=["permit.created", "permit.status_changed"],
)
print(webhook.secret)  # Save this for signature verification

webhooks = client.webhooks.list()
deliveries = client.webhooks.deliveries(webhook.id)
client.webhooks.delete(webhook.id)
```

## Context manager

```python
with BoringAPI("bp_live_sk_...") as client:
    permits = client.permits.list(state="TX")
```

## Error handling

```python
from boringapi._exceptions import NotFoundError, RateLimitError

try:
    permit = client.permits.get("pmt_nonexistent")
except NotFoundError as e:
    print(e.message)
except RateLimitError:
    print("Slow down!")
```

## Configuration

```python
client = BoringAPI(
    "bp_live_sk_...",
    base_url="https://api.boringapi.dev/v1",  # default
    timeout=30.0,                               # seconds, default
)
```
