deeplife
Official DeepLife Python toolkit for TwinCell and related analysis: call the Open API from Python, pseudo-bulk with deeplife.pseudobulk, and run sample-level differential expression with deeplife.differential_expression (suitable for pseudo-bulk, bulk, or other compatible count tables). TwinCell code is split into focused subpackages under deeplife.twincell (HTTP client, workflows, preprocess, validation); deeplife.twincell itself still exposes a flat import surface for notebooks.
Source: github.com/deeplifeai/deeplife · Documentation: twincell.deeplife.co/docs · Python: 3.12+ (see pyproject.toml).
Install
pip install deeplife
API key: you need a DeepLife key (usually dl_…). Create or copy one from the TwinCell console (sign in, then open API keys / Keys). In code, set DEEPLIFE_API_KEY in the environment or pass api_key= when constructing the client; the client sends it as the X-API-Key header on every request (not Authorization: Bearer).
Network: the TwinCell Open API is public. The client defaults to https://open-deeplife-api.deeplife.co, reachable over the Internet. Interactive REST docs are at /docs and the schema at /openapi.json; pass base_url= to target another environment. Local-only features (pseudo-bulk, differential expression on .h5ad) do not require API connectivity.
From a git clone (contributors):
uv sync --group dev
Documentation
Hosted docs (same content as the Documentation link on PyPI):
| Guide | Description |
|---|---|
| Quick Start | pip install, optional [notebook], API keys, first TwinCell workflow |
| Tutorials | End-to-end single-cell target-validation notebook (Deucravacitinib / psoriasis) |
| API Reference | TwinCell, preprocessing, validation, pseudo-bulk, differential expression |
Source: docs/index.md.
Package layout
TwinCell (deeplife.twincell)
| Import | Role |
|---|---|
deeplife.twincell |
Convenience namespace: DeepLifeClient, TwinCell, TwinCellSession, TwinCellStudy (alias of TwinCell), read_h5ad, adata_to_h5ad_bytes, etc.; plus the preprocess helpers pseudobulk, pydeseq2 (and lazy preprocessing). |
deeplife.twincell.http |
REST client (DeepLifeClient, AsyncDeepLifeClient), request/response models, errors, HTTP helpers, logging (DeepLifeClient lives in twincell.http.client). |
deeplife.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.twincell.preprocess |
Notebook-oriented pseudo-bulk and PyDESeq2 helpers (preprocess.pseudobulk, preprocess.pydeseq2). |
deeplife.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. |
Other packages
| Import | Role |
|---|---|
deeplife.pseudobulk, deeplife.differential_expression |
Pseudo-bulk from single-cell AnnData, and sample-level DE (CLIs twincell-pseudobulk, twincell-diffexpr) |
Install with pip install deeplife. Import deeplife.twincell (flat or by submodule), deeplife.pseudobulk, and deeplife.differential_expression.
Minimal API usage
End-to-end flow: build a control and a perturbed AnnData plus a DEG list yourself → submit them as a split target-validation run → poll → read the target score and causal mechanism.
The notebook-oriented TwinCell class is the shortest path. It validates the split inputs locally, checks API connectivity on construction, and submits with job_type="target_validation":
import os
from deeplife.twincell import TwinCell
tc = TwinCell(
pdata_control=pdata_control, # AnnData, raw counts in .X
pdata_pert=pdata_pert, # AnnData, raw counts in .X
degs=degs, # list[str] of HGNC-style symbols
api_key=os.environ["DEEPLIFE_API_KEY"],
)
prediction_id = tc.target_validation(target="TYK2|PROTEIN")
print(tc.get_target_score(prediction_id=prediction_id))
The same run through the HTTP client, when you want to manage polling yourself:
import os
from deeplife.twincell.http import DeepLifeClient
client = DeepLifeClient(api_key=os.environ["DEEPLIFE_API_KEY"])
prediction = client.create_prediction_split(
pdata_control=pdata_control,
pdata_pert=pdata_pert,
degs=degs,
target="TYK2|PROTEIN", # required
)
final = client.wait_for_prediction(prediction_id=prediction.prediction_id)
print(final.status)
Each prediction scores one target: pass
pdata_control,pdata_pert,degs, andtargettocreate_prediction_split. (pdata_control/pdata_pertare the Python arguments;dataset_control/dataset_pertare the REST field names onPOST /v1/predictions, not SDK parameters.)
Defaults: the client targets https://open-deeplife-api.deeplife.co; pass base_url= for another environment. Retries apply to safe GET-style calls (polling), not duplicate uploads on POST. Polling waits 5s between status requests (poll_interval_seconds) to stay well inside the edge rate limit of 30 requests/minute per IP — lower it only if you know the address isn't shared. For TLS/proxy issues, use tls_verify= and trust_env= on the client—see DeepLifeClient in deeplife.twincell.http.client.
For richer AnnData preparation (QC, column mapping, pseudo-bulk), use deeplife.twincell.preprocess or the tutorial notebooks.
Tutorials
Tutorial .ipynb files are published on the docs site (interactive + download). target-validation-deucravacitinib-psoriasis.ipynb is the end-to-end walkthrough: it loads a public psoriasis skin atlas (GSE162183), builds pseudo-bulk profiles for psoriatic vs. normal dendritic cells, derives the disease signature with PyDESeq2, then uses TwinCell to test whether Deucravacitinib's target (TYK2) causally explains it.
Run locally from a git clone:
pip install "deeplife[notebook]" jupyterlab
git clone https://github.com/deeplifeai/deeplife
cd deeplife
jupyter lab tutorials/
Set DEEPLIFE_API_KEY (or use the notebook getpass prompt) before the TwinCell API steps. Everything up to that point runs locally; the API cells need an Internet connection.
| Location | Role |
|---|---|
| twincell.deeplife.co/docs/tutorials/ | Canonical hosted tutorials (browse or download) |
tutorials/ in a git clone |
Same notebooks for local Jupyter |
Contributors can use uv sync --group dev --extra notebook instead of pip if you prefer the locked lockfile.
After
pip install -U deeplife, confirm imports match the layout you expect; the latest release is always on PyPI.
Development
uv sync --group dev
make check-all # or: ruff, mypy, pytest — see Makefile
CI: .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 bumps GitHub Actions weekly.
Releases to PyPI: .github/workflows/pypi-publish.yml runs the same checks, then publishes with OIDC trusted publishing (GitHub environment pypi, trusted publisher configured on the deeplife 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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deeplife-1.0.5.tar.gz.
File metadata
- Download URL: deeplife-1.0.5.tar.gz
- Upload date:
- Size: 708.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f94e59af92546c9559ebbe2dde525171fca530ff87dfc6f2eca282254ad40cf
|
|
| MD5 |
c1b913e2124eaafa2710125f4139cd7d
|
|
| BLAKE2b-256 |
8ab20e12172d6fa68f9d32886fe838ed550ae2b8014de80d385f45e29a5f5cab
|
Provenance
The following attestation bundles were made for deeplife-1.0.5.tar.gz:
Publisher:
pypi-publish.yml on deeplifeai/deeplife
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deeplife-1.0.5.tar.gz -
Subject digest:
1f94e59af92546c9559ebbe2dde525171fca530ff87dfc6f2eca282254ad40cf - Sigstore transparency entry: 2601598886
- Sigstore integration time:
-
Permalink:
deeplifeai/deeplife@0ff913c904ae93574f16ecb44f96c5ab4a128dbf -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/deeplifeai
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@0ff913c904ae93574f16ecb44f96c5ab4a128dbf -
Trigger Event:
push
-
Statement type:
File details
Details for the file deeplife-1.0.5-py3-none-any.whl.
File metadata
- Download URL: deeplife-1.0.5-py3-none-any.whl
- Upload date:
- Size: 181.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b0097425021dfd39c1637fd931d15840020b20eb23dbbd90eb3416527a944fb
|
|
| MD5 |
87689c08384c20d4b0916d53ce6252af
|
|
| BLAKE2b-256 |
bec43ff4558cdd7161e9c8c62fc128166394be5695a1b6a8c2462bedb3583e2e
|
Provenance
The following attestation bundles were made for deeplife-1.0.5-py3-none-any.whl:
Publisher:
pypi-publish.yml on deeplifeai/deeplife
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deeplife-1.0.5-py3-none-any.whl -
Subject digest:
0b0097425021dfd39c1637fd931d15840020b20eb23dbbd90eb3416527a944fb - Sigstore transparency entry: 2601599238
- Sigstore integration time:
-
Permalink:
deeplifeai/deeplife@0ff913c904ae93574f16ecb44f96c5ab4a128dbf -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/deeplifeai
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@0ff913c904ae93574f16ecb44f96c5ab4a128dbf -
Trigger Event:
push
-
Statement type: