Metadata-Version: 2.4
Name: euleris
Version: 0.1.0
Summary: Topological molecular analysis — Python client for the Euleris API
Author-email: David Martin Venti <david.martin@cognitive-engineering.dev>
License: Proprietary
Project-URL: Homepage, https://cognitive-engineering.dev
Project-URL: Documentation, https://cognitive-engineering.dev/euleris/app/api-docs
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Provides-Extra: pandas
Requires-Dist: pandas>=1.5; extra == "pandas"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: responses>=0.23; extra == "dev"
Dynamic: license-file

# euleris

Topological molecular analysis — the official Python client for the **Euleris API**.

`euleris` is a **thin HTTP client**. All computation (spectrum extraction, scoring,
ADME/toxicity prediction, similarity search) runs **server-side** on the Euleris
compute engine. The client just sends SMILES and returns typed results.

## Install

```bash
pip install euleris
# optional: DataFrame support
pip install "euleris[pandas]"
```

## Authentication

Get an API key (`ek_...`) from https://cognitive-engineering.dev/pricing.

Provide it in any of these ways (checked in this order):

1. Environment variable:
   ```bash
   export EULERIS_API_KEY=ek_your_key
   ```
2. Config file `~/.euleris/config`:
   ```ini
   [default]
   api_key = ek_your_key
   ```
3. Explicitly in code:
   ```python
   import euleris
   euleris.configure(api_key="ek_your_key")
   ```

## Quickstart

```python
import euleris

# Analyze a single molecule
result = euleris.analyze("CCO")
print(result.score)          # topological score
print(result.spectrum)       # {"N3": 0, "N6": 1, ...}
print(result.meta.atoms)     # 3

# Batch analysis
batch = euleris.batch(["CCO", "c1ccccc1", "CC(=O)O"])
print(batch.stats)           # {"total": 3, "valid": 3, "invalid": 0}
df = batch.to_dataframe()    # requires euleris[pandas]

# Compare two molecules
cmp = euleris.compare("c1ccccc1", "c1ccncc1")
print(cmp.delta_score)

# Similarity search
sim = euleris.similar("c1ccccc1", top_k=5, library="zinc")
for match in sim.matches:
    print(match.smiles, match.similarity)
```

### Using an explicit client

```python
from euleris import EulerisClient

client = EulerisClient(api_key="ek_your_key")
result = client.analyze("CCO")
```

## Error handling

```python
from euleris import EulerisError, AuthError, RateLimitError, InvalidSmilesError

try:
    euleris.analyze("not-a-molecule")
except InvalidSmilesError as e:
    print("Bad SMILES:", e)
except RateLimitError as e:
    print("Slow down:", e)
except AuthError as e:
    print("Check your key:", e)
except EulerisError as e:
    print("Something went wrong:", e)
```

## Links

- API docs: https://cognitive-engineering.dev/euleris/app/api-docs
- Pricing / API keys: https://cognitive-engineering.dev/pricing

## License

Proprietary. Copyright (c) 2026 Cognitive Engineering / David Martin Venti.
