Metadata-Version: 2.4
Name: ligandai
Version: 0.6.9
Summary: LIGANDAI Enterprise API - Peptide Therapeutic Design Platform
Home-page: https://ligandal.com
Author: Ligandal Inc.
Author-email: "Ligandal Inc." <support@ligandal.com>
License: Proprietary - Ligandal Inc.
Project-URL: Homepage, https://ligandal.com
Project-URL: Documentation, https://docs.ligandal.com/api
Project-URL: Repository, https://github.com/ligandal/ligandai-python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: Other/Proprietary 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: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: typer>=0.9.0
Requires-Dist: aiohttp>=3.8.0
Requires-Dist: tqdm>=4.65.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.0.280; extra == "dev"
Requires-Dist: mypy>=1.4.0; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Deprecated: Historical SDK Tree

This `ligandai-api/` directory is deprecated inside `LIGANDAI_ALPHA_V2`.
Do not use it for new SDK work, release builds, or PyPI uploads. The active
LigandAI Python SDK lives at `/mnt/backup/ligandai-python-sdk`.

# LIGANDAI Python SDK

[![PyPI version](https://badge.fury.io/py/ligandai.svg)](https://badge.fury.io/py/ligandai)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-Proprietary-red.svg)](https://ligandal.com/legal/api-terms)
[![Documentation](https://img.shields.io/badge/docs-ligandal.com-green.svg)](https://docs.ligandal.com/api)

Official Python SDK for the LIGANDAI Enterprise API - AI-powered peptide therapeutic design, comparative transcriptomics, and structure prediction.

## Features

- **Comparative Transcriptomics**: Tissue-specific expression analysis using GTEx/HPA data
- **Structure Fetching**: Batch PDB and AlphaFold structure downloads
- **Structure Prediction**: Boltz-2 and AlphaFold2 folding via GPU clusters
- **Binding Energy**: Interface energetics and binding affinity calculations
- **Async/Await**: Full async support for concurrent operations

## Installation

```bash
pip install ligandai
```

### Requirements

- Python 3.9+
- An active LIGANDAI subscription (Basic, Academia, Pro, or Enterprise)
- API key from your [LIGANDAI Dashboard](https://ligandal.com/settings/api)

## Command Line Interface

The LIGANDAI SDK includes a comprehensive CLI for all API operations.

### CLI Installation & Configuration

```bash
# Install the package
pip install ligandai

# Configure your API key
ligandai auth configure --api-key lgai_ent_YOUR_KEY

# Verify authentication
ligandai auth verify

# Check credit balance
ligandai auth credits
```

### CLI Quick Examples

```bash
# Transcriptomics
ligandai transcriptomics tissues                    # List available tissues
ligandai transcriptomics analyze \
  --target heart --target skeletal_muscle \
  --exclude liver --top-n 50

# Structure Fetching
ligandai structures fetch P01308 --output insulin.pdb
ligandai structures batch --id P01308 --id P01375 --output-dir ./structures

# Structure Prediction
ligandai folding predict MKTLLILTGLAV... --model boltz2 --gpu H200
ligandai folding predict --fasta sequence.fasta --wait
ligandai folding status fold_abc123
ligandai folding download fold_abc123 --output ./results

# Energy Calculations
ligandai energy calculate complex.pdb \
  --target A --target B --binder C

# Batch Exports
ligandai queue export --analysis analysis_123 --structures
ligandai queue status export_456
ligandai queue download export_456 --output ./exports
```

See [CLI Documentation](#cli-reference) below for complete reference.

## Quick Start

```python
import asyncio
from ligandai import LigandAI

async def main():
    # Initialize with your API key
    client = LigandAI(api_key="lig_ent_your_api_key")

    # Get user info
    user = await client.get_user_info()
    print(f"Authenticated as: {user.email} ({user.subscription_tier})")

    # Check credit balance
    credits = await client.get_credits()
    print(f"Available credits: {credits.available_balance:,}")

    # Run transcriptomics analysis
    result = await client.transcriptomics.analyze(
        target_tissues=["heart", "skeletal_muscle"],
        exclude_tissues=["liver", "kidney"],
        top_n=50,
        receptor_only=True
    )

    print(f"Found {len(result.markers)} tissue-specific markers:")
    for marker in result.markers[:5]:
        print(f"  {marker.gene_name}: SI={marker.specificity_index:.2f}")

    # Fetch structures for markers
    structures = await client.structures.fetch_batch(
        uniprot_ids=[m.uniprot_accession for m in result.markers[:10]]
    )

    print(f"Fetched {structures.summary.succeeded} structures")

    # Submit folding job
    job = await client.folding.predict(
        model="boltz2",
        sequence="MKTLLILTGLAVLLSAAPASAGGSC...",
        gpu_type="H200"
    )

    print(f"Folding job submitted: {job.job_id}")

    # Wait for completion
    completed = await client.folding.wait_for_completion(
        job_id=job.job_id,
        timeout=3600
    )

    print(f"Folding complete! pLDDT: {completed.result.metrics.plddt_mean:.1f}")

    # Download structure
    pdb_content = await client.folding.download_structure(
        job_id=job.job_id,
        format="pdb"
    )

    with open("prediction.pdb", "w") as f:
        f.write(pdb_content)

asyncio.run(main())
```

## Authentication

Store your API key securely using environment variables:

```bash
export LIGANDAI_API_KEY="lig_ent_your_api_key"
```

```python
import os
from ligandai import LigandAI

client = LigandAI(api_key=os.environ["LIGANDAI_API_KEY"])
```

## API Reference

### Transcriptomics

```python
# Full comparative analysis
result = await client.transcriptomics.analyze(
    target_tissues=["heart", "skeletal_muscle"],
    exclude_tissues=["liver"],
    top_n=100,
    receptor_only=True,
    min_si=2.0
)

# Quick TPM analysis
quick = await client.transcriptomics.analyze_quick(
    target_tissues=["brain"],
    top_n=50
)

# Get expression data for a gene
expression = await client.transcriptomics.get_expression("EGFR")

# Get organ systems hierarchy
organs = await client.transcriptomics.get_organ_systems()

# Save analysis
saved = await client.transcriptomics.save_analysis(
    name="My Analysis",
    analysis=result
)

# List saved analyses
analyses = await client.transcriptomics.list_analyses()

# Export to CSV
export = await client.transcriptomics.export(
    analysis_id="analysis_xyz789",
    format="csv"
)
```

### Structures

```python
# Fetch from AlphaFold
structure = await client.structures.fetch(
    source="alphafold",
    uniprot_id="P01308"
)

# Fetch from PDB
pdb_structure = await client.structures.fetch(
    source="pdb",
    pdb_id="1TRZ",
    chain="A"
)

# Batch fetch multiple structures
batch = await client.structures.fetch_batch(
    uniprot_ids=["P01308", "P01375", "P01579"]
)

# Search PDB
results = await client.structures.search_pdb(
    query="EGFR kinase",
    filters={
        "resolution": {"max": 2.0},
        "organism": "Homo sapiens"
    }
)

# Upload custom structure
custom = await client.structures.upload_custom(
    pdb_content=pdb_string,
    name="My Structure",
    gene_name="CUSTOM1"
)

# Share structure
share = await client.structures.share(
    job_id="fold_abc123",
    expires_in_days=30
)
```

### Folding

```python
# Single protein prediction
job = await client.folding.predict(
    model="boltz2",
    sequence="MKTLLILTGLAVLLSAAPASAGGSC...",
    gpu_type="H200"
)

# Multi-chain complex
job = await client.folding.predict(
    model="boltz2",
    entities=[
        {
            "type": "protein",
            "chain_id": "A",
            "sequence": "MKTLLILTGLAVLLSAAPASAGGSC...",
            "gene_name": "INS"
        },
        {
            "type": "protein",
            "chain_id": "B",
            "sequence": "FVNQHLCGSHLVEALYLVCGERGFFYTPKT"
        },
        {
            "type": "ligand",
            "chain_id": "X",
            "sequence": "ZN"
        }
    ],
    gpu_type="H200",
    gpu_count=2,
    accelerated_mode=True
)

# Check status
status = await client.folding.get_status(job_id=job.job_id)

# Wait for completion
result = await client.folding.wait_for_completion(
    job_id=job.job_id,
    timeout=3600,
    poll_interval=10
)

# Download structure
pdb = await client.folding.download_structure(
    job_id=job.job_id,
    format="pdb"
)

# Export full results
export = await client.folding.export(
    job_id=job.job_id,
    format="zip",
    include_pae=True
)

# Check complex type before submitting
check = await client.folding.check_complex(
    entities=[
        {"type": "protein", "chain_id": "A", "sequence": "..."},
        {"type": "ligand", "chain_id": "X", "sequence": "ATP"}
    ]
)
print(f"Estimated credits: {check.estimated_credits}")
```

### Credits

```python
# Get balance
credits = await client.get_credits()
print(f"Balance: {credits.balance}")
print(f"Available: {credits.available_balance}")

# Get transactions
transactions = await client.get_transactions(
    type="usage_gpu",
    limit=50
)

# Purchase credits
purchase = await client.purchase_credits(amount=100)

# Configure auto-replenish
await client.configure_auto_replenish(
    enabled=True,
    threshold=10000,
    amount=100
)
```

## Synchronous Usage

For non-async code, use the synchronous wrapper:

```python
from ligandai import LigandAI

client = LigandAI(api_key="lig_ent_your_api_key")

# Use sync_ prefix for synchronous calls
user = client.sync_get_user_info()
result = client.transcriptomics.sync_analyze(
    target_tissues=["heart"]
)
```

## Error Handling

```python
from ligandai import LigandAI
from ligandai.exceptions import (
    AuthenticationError,
    InsufficientCreditsError,
    TierRestrictionError,
    RateLimitError,
    ValidationError
)

client = LigandAI(api_key="lig_ent_your_api_key")

try:
    result = await client.transcriptomics.analyze(
        target_tissues=["heart"]
    )
except AuthenticationError as e:
    print(f"Invalid API key: {e}")
except InsufficientCreditsError as e:
    print(f"Need {e.required} credits, have {e.available}")
except TierRestrictionError as e:
    print(f"Requires {e.required_tier} tier, you have {e.current_tier}")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except ValidationError as e:
    print(f"Validation error: {e.details}")
```

## Configuration

```python
from ligandai import LigandAI

client = LigandAI(
    api_key="lig_ent_your_api_key",
    base_url="https://api.ligandal.com/v1",  # Default
    timeout=30.0,  # Request timeout in seconds
    max_retries=3,  # Retry on transient errors
    verify_ssl=True  # SSL verification
)
```

## Rate Limits

| Tier | Requests/Hour | Concurrent GPU Jobs |
|------|---------------|---------------------|
| Basic | 100 | 1 |
| Academia | 500 | 2 |
| Pro | 1,000 | 4 |
| Enterprise | 10,000 | 8 |

Rate limit headers are accessible on responses:

```python
result = await client.transcriptomics.analyze(...)
print(f"Remaining: {result.rate_limit.remaining}")
print(f"Reset: {result.rate_limit.reset}")
```

## GPU Pricing

Standard Boltz-2 folding uses deterministic per-trajectory pricing from the API response. Benchmark alternatives are billed separately:

| Workload | Credits |
|----------|---------|
| BoltzGen, BindCraft, RFdiffusion2/3, PepMLM baselines | 2,500 / B200+ hr (41.67/min, minimum 1 minute) |

These alternatives are benchmark-only comparison paths and are not the default LigandForge generation + folding workflow.

## Development

### Install from source

```bash
git clone https://github.com/ligandal/ligandai-python.git
cd ligandai-python
pip install -e ".[dev]"
```

### Run tests

```bash
pytest
```

### Type checking

```bash
mypy src/ligandai
```

### Code formatting

```bash
black src/ligandai
ruff check src/ligandai
```

## Documentation

- **Full API Documentation**: [docs.ligandal.com/api](https://docs.ligandal.com/api)
- **OpenAPI Specification**: [Available in this package](./docs/openapi.yaml)
- **Examples**: [GitHub Repository](https://github.com/ligandal/ligandai-python/tree/main/examples)

## Support

- **Email**: support@ligandal.com
- **Enterprise Support**: enterprise@ligandal.com
- **GitHub Issues**: [ligandal/ligandai-python](https://github.com/ligandal/ligandai-python/issues)
- **Status Page**: [status.ligandal.com](https://status.ligandal.com)

## License

This SDK is proprietary software. See [API Terms of Use](https://ligandal.com/legal/api-terms) for details.

Copyright (c) 2025 Ligandal Inc. All rights reserved.

## CLI Reference

### Authentication Commands

```bash
# Configure API key
ligandai auth configure --api-key YOUR_KEY
ligandai auth configure --base-url https://api.ligandal.com/v1

# Show current configuration
ligandai auth configure --show

# Verify API key
ligandai auth verify [--json]

# Check credit balance
ligandai auth credits [--json]

# View usage statistics
ligandai auth usage [--start 2025-01-01] [--end 2025-01-31] [--json]
```

### Transcriptomics Commands

```bash
# List available tissues
ligandai transcriptomics tissues [--json]

# Run comparative analysis
ligandai transcriptomics analyze \
  --target heart \
  --target skeletal_muscle \
  --exclude liver \
  --exclude kidney \
  --min-tpm 1.0 \
  --min-si 0.5 \
  --top-n 100 \
  --receptor-only \
  --output results.json

# Get expression for a gene
ligandai transcriptomics expression EGFR \
  --tissue heart \
  --tissue brain \
  [--json]
```

### Structure Commands

```bash
# Fetch single structure
ligandai structures fetch P01308 \
  --source alphafold \
  --output insulin.pdb

ligandai structures fetch 1TRZ \
  --source pdb \
  --experimental \
  --output 1trz.pdb

# Batch fetch
ligandai structures batch \
  --id P01308 \
  --id P01375 \
  --id P01579 \
  --output-dir ./structures \
  --format zip

# Batch from file
ligandai structures batch \
  --file uniprots.txt \
  --output-dir ./batch \
  --format tar
```

### Folding Commands

```bash
# Predict structure from sequence
ligandai folding predict MKTLLILTGLAV... \
  --model boltz2 \
  --gpu H200 \
  --output prediction.pdb \
  --wait

# Predict from FASTA file
ligandai folding predict \
  --fasta sequence.fasta \
  --model alphafold2 \
  --gpu A100_80GB \
  --no-wait

# Check job status
ligandai folding status fold_abc123 [--json]

# Download completed job
ligandai folding download fold_abc123 \
  --output ./results

# List recent jobs
ligandai folding list \
  [--status completed] \
  [--limit 20] \
  [--json]
```

### Energy Commands

```bash
# Calculate binding energy
ligandai energy calculate complex.pdb \
  --target A \
  --target B \
  --binder C \
  --method ptmenergy \
  --output energy.json

# Identify binding hotspots
ligandai energy hotspots structure.pdb \
  --chain A \
  --threshold -1.0 \
  [--json]
```

### Queue Commands

```bash
# Create batch export
ligandai queue export \
  --analysis analysis_123 \
  --structures \
  --generate-missing \
  --format zip \
  --output ./exports

# Export specific markers
ligandai queue export \
  --marker EGFR \
  --marker CD4 \
  --marker TNF \
  --structures

# Check export status
ligandai queue status export_456 [--json]

# Download completed export
ligandai queue download export_456 \
  --output ./exports

# List recent exports
ligandai queue list \
  [--status completed] \
  [--limit 20] \
  [--json]
```

### Global Options

All commands support these global options:

```bash
--api-key, -k        Override configured API key
--base-url, -u       Override API base URL
--json               Output as JSON (where applicable)
--verbose            Verbose output
--help               Show command help
```

### Configuration File

Configuration is stored in `~/.ligandai/config.json`:

```json
{
  "api_key": "lgai_ent_YOUR_KEY",
  "base_url": "https://api.ligandal.com/v1"
}
```

### Environment Variables

```bash
export LIGANDAI_API_KEY="lgai_ent_YOUR_KEY"
export LIGANDAI_BASE_URL="https://api.ligandal.com/v1"
```

Priority: CLI arguments > Config file > Environment variables

## Changelog

### 1.0.0 (2024-01)

- Initial public release
- Transcriptomics API support
- Structures API support
- Folding API support (Boltz-2, AlphaFold2)
- Full async/await support
- Comprehensive error handling
- Complete CLI with all API operations
