Metadata-Version: 2.4
Name: aletheia-safety
Version: 0.4.1
Summary: Python SDK for the ALETHEIA Safety Database API — chemical safety data for 1,880+ compounds with typed responses
Author: Holistic Quality LLC
License-Expression: MIT
Project-URL: Homepage, https://api.aletheia.holisticquality.io
Project-URL: Documentation, https://api.aletheia.holisticquality.io/api/openapi
Project-URL: Repository, https://github.com/holisticquality/aletheia-safety-python
Keywords: chemical-safety,toxicology,aletheia,compounds,regulatory,safety-data
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
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 :: Scientific/Engineering :: Chemistry
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# aletheia-safety

Python SDK for the [ALETHEIA Safety Database API](https://api.aletheia.holisticquality.io) — chemical safety data for 1,800+ compounds, 950+ materials, and 520+ consumer products.

## Install

```bash
pip install aletheia-safety
```

## Quick Start

```python
from aletheia_safety import Aletheia

# Free tier (500 requests/day per IP)
client = Aletheia()

# Or with an API key for higher limits
client = Aletheia(api_key="aletheia_live_…")
```

## Usage

### Look up compounds

```python
# By HQ ID
glyphosate = client.compound("hq-c-org-000001")
print(glyphosate["name"])  # "Glyphosate"

# By CAS number
bpa = client.compound_by_cas("80-05-7")

# With safety context
risk = client.compound("hq-c-org-000001", context="human_adult")

# Batch lookup (up to 20)
results = client.batch(["hq-c-org-000001", "hq-c-org-000005"])
```

### Search

```python
# Full-text search across all entity types
results = client.search("sodium")

# Filter by type
compounds = client.search("sodium", type="compound", limit=10)

# Filter by risk level and context
high_risk = client.filter(risk="high", context="food_contact")

# Filter by regulatory agency
epa = client.filter(agency="EPA", year_min=2020)
```

### Compare compounds

```python
# Side-by-side comparison (2-5 compounds)
comparison = client.compare(
    ["hq-c-org-000001", "hq-c-org-000005"],
    context="human_adult"
)
```

### Explore relationships

```python
# Direct relationships
rels = client.relationships("hq-c-org-000001")

# Multi-hop graph traversal
graph = client.graph("hq-c-org-000001", depth=2)
print(f"{len(graph['nodes'])} nodes, {len(graph['edges'])} edges")
```

### Regulatory data

```python
# Classifications for a compound
reg = client.regulatory("hq-c-org-000001")

# All agencies
agencies = client.regulatory_agencies()

# Compounds classified by a specific agency
iarc = client.regulatory_by_agency("IARC")
```

### Exposure sources

```python
# Where a compound is found
sources = client.found_in("hq-c-org-000001")

# All categories
cats = client.found_in_categories()

# Compounds in a category
food = client.found_in_by_category("Food")
```

### Products & Materials

```python
products = client.products(limit=50)
product = client.product("hq-p-hom-000001")

materials = client.materials(limit=50)
material = client.material("hq-m-str-000001")
```

### Fragrance ingredients

```python
fragrances = client.fragrance(limit=50)
classes = client.fragrance_classes()
results = client.fragrance_search("lavender")
```

### Embeddable badge

```python
url = client.badge_url("hq-c-org-000001")
# Use in HTML: <img src="{url}" alt="Safety badge"/>
```

### Key management

```python
status = client.key_status()
print(f"Tier: {status['tier']}, Used: {status['usage']['today']}")

# Rotate a compromised key (client auto-updates)
result = client.key_rotate()
print(f"New key: {result['key']}")

# Usage history
usage = client.key_usage(days=14)
for day in usage["usage"]:
    print(f"{day['date']}: {day['requests']} requests")
```

### Watchlist (Developer+)

```python
# Add compounds to your watchlist
client.watchlist_add(["hq-c-org-000001", "hq-c-org-000033"])

# List watched compounds with enrichment
watched = client.watchlist()

# Remove a compound
client.watchlist_remove("hq-c-org-000033")
```

### Changelog (Developer+)

```python
# Recent regulatory/data changes
changes = client.changelog(limit=20)

# Filter by date and compound
changes = client.changelog(since="2026-03-01", compound_id="hq-c-org-000001")
```

### Raw data access (Developer+)

```python
raw = client.compound_raw("hq-c-org-000001")
raw_product = client.product_raw("hq-p-hom-000001")
```

## Tiers

| Tier | Requests/Day | Price |
|------|-------------|-------|
| Public | 500/IP | Free |
| Developer | 10,000 | $29/mo |
| Pro | 100,000 | $99/mo |
| Enterprise | Unlimited | Contact |

Get an API key at [aletheia.holisticquality.io/pricing](https://aletheia.holisticquality.io/pricing).

## Error Handling

```python
from aletheia_safety import Aletheia, AletheiaError, RateLimitError

client = Aletheia()

try:
    compound = client.compound("invalid-id")
except RateLimitError:
    print("Rate limit exceeded — wait or upgrade your tier")
except AletheiaError as e:
    print(f"API error {e.status}: {e}")
```

## License

MIT
