Metadata-Version: 2.4
Name: deeplife-toolkit
Version: 0.1.8
Summary: Official DeepLife Python toolkit on PyPI: TwinCell (`deeplife_toolkit.twincell`), pseudo-bulk (`deeplife_toolkit.pseudobulk`), differential expression (`deeplife_toolkit.differential_expression`). Optional `[notebook]` extra for Jupyter; bundled tutorials under `deeplife_toolkit.notebooks`.
Project-URL: Homepage, https://deeplife.co
Project-URL: Documentation, https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/README.md
Project-URL: Repository, https://github.com/deeplifeai/deeplife-toolkit
Project-URL: Issues, https://github.com/deeplifeai/deeplife-toolkit/issues
Project-URL: Changelog, https://github.com/deeplifeai/deeplife-toolkit/releases
Author-email: DeepLife <hello@deeplife.co>
License: MIT
License-File: LICENSE
Keywords: anndata,api,bioinformatics,deeplife,differential-expression,digital-twin,drug-discovery,pseudobulk,scanpy,single-cell,twincell
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: anndata>=0.12.7
Requires-Dist: boto3>=1.35.0
Requires-Dist: decoupler>=2.1.1
Requires-Dist: gseapy>=1.1.13
Requires-Dist: h5py>=3.10.0
Requires-Dist: hdf5plugin>=5.1.0
Requires-Dist: httpx>=0.27.2
Requires-Dist: hydra-core>=1.3.0
Requires-Dist: ipykernel>=7.1.0
Requires-Dist: kaleido>=1.0.0
Requires-Dist: networkx>=3.2.1
Requires-Dist: numpy>=1.26.4
Requires-Dist: omegaconf>=2.3.0
Requires-Dist: pandas>=2.2.3
Requires-Dist: plotly>=6.3.0
Requires-Dist: pyarrow>=21.0.0
Requires-Dist: pydantic>=2.8.2
Requires-Dist: pydeseq2>=0.5.2
Requires-Dist: pygraphviz>=1.14
Requires-Dist: pyyaml>=6.0
Requires-Dist: scanpy[leiden]>=1.11.4
Requires-Dist: tenacity>=9.0.0
Requires-Dist: tqdm>=4.67.1
Provides-Extra: notebook
Requires-Dist: adjusttext>=0.8.0; extra == 'notebook'
Requires-Dist: comm>=0.1.1; extra == 'notebook'
Requires-Dist: gseapy>=1.1.9; extra == 'notebook'
Requires-Dist: ipython>=8.26.0; extra == 'notebook'
Requires-Dist: six>=1.5; extra == 'notebook'
Description-Content-Type: text/markdown

# deeplife-toolkit

[![PyPI version](https://img.shields.io/pypi/v/deeplife-toolkit)](https://pypi.org/project/deeplife-toolkit/)
[![CI](https://github.com/deeplifeai/deeplife-toolkit/actions/workflows/ci.yml/badge.svg)](https://github.com/deeplifeai/deeplife-toolkit/actions/workflows/ci.yml)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Official **[DeepLife](https://deeplife.co/)** Python **toolkit** for **TwinCell** and related analysis: call the Open API from Python, **pseudo-bulk** with **`deeplife_toolkit.pseudobulk`**, and run **sample-level differential expression** with **`deeplife_toolkit.differential_expression`** (suitable for pseudo-bulk, bulk, or other compatible count tables). TwinCell code is split into focused subpackages under **`deeplife_toolkit.twincell`** (HTTP client, workflows, preprocess, validation); **`deeplife_toolkit.twincell`** itself still exposes a flat import surface for notebooks.

**Source:** [github.com/deeplifeai/deeplife-toolkit](https://github.com/deeplifeai/deeplife-toolkit) · **Documentation:** [docs index on GitHub](https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/README.md) · **Python:** 3.12+ (see [`pyproject.toml`](https://github.com/deeplifeai/deeplife-toolkit/blob/main/pyproject.toml)).

---

## Install

```bash
pip install deeplife-toolkit
```

**API key:** you need a DeepLife key (usually `dl_…`). Create or copy one from the **[TwinCell console](https://twincell.deeplife.co/)** (sign in, then open **API keys** / **Keys**). In code, set `DEEPLIFE_API_KEY` in the environment or pass `api_key=` when constructing the client. API documentation for your deployment is usually at `{base_url}/docs` when enabled (the client defaults to the production Open API host; pass `base_url=` for another environment).

**Network:** the TwinCell **Open API** is **not** on the public Internet today. It runs in DeepLife’s cluster and is reachable only when your machine has access to that network—for example by being signed into your organization’s **[Tailscale](https://tailscale.com/)** tailnet (or whatever access path your team documents). Local-only features (pseudo-bulk, differential expression on `.h5ad`) do **not** require API connectivity.

**From a git clone** (contributors):

```bash
uv sync --group dev
```

---

## Documentation

Long-form guides (same content as the **`Documentation`** link on [PyPI](https://pypi.org/project/deeplife-toolkit/)):

| Guide | Description |
|--------|----------------|
| [Installation](https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/installation.md) | `pip install`, optional **`[notebook]`**, API keys, verify imports |
| [Pseudo-bulk & differential expression](https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/pseudobulk-differential-expression.md) | `AnnData` → pseudo-bulk, sample-level DE, CLIs |
| [TwinCell Open API (Python)](https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/twincell-open-api.md) | HTTP client (`twincell.http`), workflows, predictions, studies, datasets |

Index: [docs/README.md](https://github.com/deeplifeai/deeplife-toolkit/blob/main/docs/README.md).

---

## Package layout

### TwinCell (`deeplife_toolkit.twincell`)

| Import | Role |
|--------|------|
| **`deeplife_toolkit.twincell`** | Convenience namespace: `OpenDeepLifeClient`, `TwinCell`, `TwinCellSession`, `TwinCellStudy` (alias of `TwinCell`), `read_h5ad`, `adata_to_h5ad_bytes`, etc.; lazy attributes for the heavy preprocess stack (`preprocessing`, `pseudobulk`, `pydeseq2`, `reporting_pipeline`). |
| **`deeplife_toolkit.twincell.http`** | REST client (`OpenDeepLifeClient`, `AsyncOpenDeepLifeClient`), request/response models, errors, HTTP helpers, logging (`OpenDeepLifeClient` lives in `twincell.http.client`). |
| **`deeplife_toolkit.twincell.workflows`** | High-level session and study code: import submodules explicitly, e.g. `twincell.workflows.workflows` (`TwinCellSession`, …), `twincell.workflows.study` (`TwinCell`, …), `twincell.validation.upload_helpers` (`adata_to_h5ad_bytes` for client-side serialization), `twincell.workflows.h5ad_io` (`read_h5ad` for local paths and remote `.h5ad` URIs). The package `__init__` resolves names lazily to avoid import cycles. |
| **`deeplife_toolkit.twincell.preprocess`** | Notebook-oriented pseudo-bulk and PyDESeq2 orchestration (`preprocess.preprocessing`, `preprocess.reporting_pipeline`). |
| **`deeplife_toolkit.twincell.validation`** | Local checks for the **split inference** upload path (`validate_twincell_split_anndata`, shared with the HTTP client). Exceptions live under **`validation.core`**; shared result types under **`validation.checks`**. |
| **`deeplife_toolkit.twincell.viz`** | Optional plotting helpers (e.g. causal graph / Parquet bundles). |

### Other packages

| Import | Role |
|--------|------|
| `deeplife_toolkit.pseudobulk`, `deeplife_toolkit.differential_expression` | Pseudo-bulk from single-cell `AnnData`, and sample-level DE (CLIs `twincell-pseudobulk`, `twincell-diffexpr`) |
| `deeplife_toolkit.notebooks` | **Bundled Jupyter tutorials** (PyPI wheel); see [`packaged_notebooks_directory()`](#example-notebooks) |

Install with **`pip install deeplife-toolkit`** (PyPI **project** name, hyphen). **Import** **`deeplife_toolkit.twincell`** (flat or by submodule), **`deeplife_toolkit.pseudobulk`**, and **`deeplife_toolkit.differential_expression`** (nested packages inside the `deeplife_toolkit` distribution).

---

## Minimal API usage

End-to-end flow: prepare `.h5ad` or `AnnData` yourself → `create_prediction` (single file) or `create_prediction_split` (control + perturbed + DEGs; validated locally) → poll or `watch_prediction` → read `results` (and optional influence / causal helpers).

```python
import os
from deeplife_toolkit.twincell import OpenDeepLifeClient

client = OpenDeepLifeClient(api_key=os.environ["DEEPLIFE_API_KEY"])
prediction = client.create_prediction(dataset="twincell_ready.h5ad")
final = client.wait_for_prediction(prediction_id=prediction.prediction_id)
print(final.status)
```

The same client is available explicitly as **`from deeplife_toolkit.twincell.http import OpenDeepLifeClient`** (recommended in application code so imports stay close to the HTTP layer).

**Defaults:** the client uses the toolkit’s configured API base URL; pass `base_url=` for another environment. You must be able to reach that host from your network (see **Network** under [Install](#install)). Retries apply to safe **GET**-style calls (polling), not duplicate uploads on `POST`. For TLS/proxy issues, use `tls_verify=` and `trust_env=` on the client—see **`OpenDeepLifeClient`** in **`deeplife_toolkit.twincell.http.client`**.

For richer AnnData preparation (QC, column mapping, pseudo-bulk), use **`deeplife_toolkit.twincell.preprocess`** or the [example notebooks](#example-notebooks).

---

## Example notebooks

Tutorial **`.ipynb`** files are **shipped inside the PyPI wheel** under **`deeplife_toolkit/notebooks/`** (no git clone required to obtain them). **`tuto-sc.ipynb`** covers single-cell exploration, pseudo-bulk **PyDESeq2**, and **`TwinCell`**. The bulk companion is **`tuto-bulk.ipynb`**.

**Repository layout:** the same files live in the repository under [`notebooks/`](notebooks/) (`tuto-sc.ipynb`, `tuto-bulk.ipynb`). That folder holds a short README and is reserved for **generated data** when you work from a clone.

### Run the Kang tutorial (PyPI only)

1. Create and activate a virtual environment, then:

   ```bash
   pip install "deeplife-toolkit[notebook]" jupyterlab seaborn
   ```

2. **(Optional)** Register this environment as a Jupyter kernel so it appears by name in the UI:

   ```bash
   python -m ipykernel.kernelspec --user --name deeplife-toolkit --display-name "Python (deeplife-toolkit)"
   ```

3. **Start JupyterLab** using the bundled notebook directory as the server root (macOS / Linux):

   ```bash
   jupyter lab --notebook-dir="$(python -c "from deeplife_toolkit.notebooks import packaged_notebooks_directory; print(packaged_notebooks_directory())")"
   ```

   **Windows (PowerShell):**

   ```powershell
   $nb = python -c "from deeplife_toolkit.notebooks import packaged_notebooks_directory; print(packaged_notebooks_directory())"
   jupyter lab --notebook-dir="$nb"
   ```

4. In JupyterLab, open **`tuto-sc.ipynb`** (or **`tuto-bulk.ipynb`**). Choose the kernel from step 2 (or the interpreter where you ran **`pip install`**).

The bundled directory usually lives under **`site-packages`** and may be **read-only** on some systems. If saving notebook outputs fails, copy **`tuto-sc.ipynb`** (or **`tuto-bulk.ipynb`**) to a writable folder, run **`jupyter lab`** from there, and open the copy.

The Kang dataset is fetched over HTTPS inside **`tuto-sc.ipynb`** using **`read_h5ad`** (from **`deeplife_toolkit.twincell`**, implemented in **`deeplife_toolkit.twincell.workflows.h5ad_io`**). **Part 2** (TwinCell HTTP) needs **`DEEPLIFE_API_KEY`** or a one-time **`getpass`** prompt, plus network access to the API (for example **Tailscale** as your org documents).

| Location | Role |
|----------|------|
| `deeplife_toolkit.notebooks.packaged_notebooks_directory()` | Path to bundled `.ipynb` files after `pip install`. |
| [`notebooks/`](notebooks/) in a **git clone** | README + local download/output paths (gitignored data). |

**Contributors** who work from a git clone can use `uv sync --group dev --extra notebook` instead of `pip` if you prefer the locked lockfile.

> After `pip install -U deeplife-toolkit`, confirm imports match the [layout](#package-layout) you expect; the latest release is always on [PyPI](https://pypi.org/project/deeplife-toolkit/).

---

## Development

```bash
uv sync --group dev
make check-all    # or: ruff, mypy, pytest — see Makefile
```

**CI:** [`.github/workflows/ci.yml`](https://github.com/deeplifeai/deeplife-toolkit/blob/main/.github/workflows/ci.yml) runs on pushes and PRs to **`main`** / **`master`**: `uv sync --frozen --group dev`, **Ruff**, **mypy**, **pytest**, **`uv build`**, **`twine check --strict`**. [`.github/dependabot.yml`](https://github.com/deeplifeai/deeplife-toolkit/blob/main/.github/dependabot.yml) bumps **GitHub Actions** weekly.

**Releases to PyPI:** [`.github/workflows/pypi-publish.yml`](https://github.com/deeplifeai/deeplife-toolkit/blob/main/.github/workflows/pypi-publish.yml) runs the same checks, then publishes with **OIDC trusted publishing** (GitHub environment **`pypi`**, trusted publisher configured on the **`deeplife-toolkit`** PyPI project). Bump **`version`** in `pyproject.toml`, push to **`main`**, then either push a tag matching **`v*`** or run the workflow manually from the **Actions** tab.
