Metadata-Version: 2.4
Name: wittgen-b2sc
Version: 0.1.1
Summary: Thin Python client for the WittGen B2SC API (bulk RNA-seq -> single-cell type proportions)
Author: WittGen
License: Apache-2.0
Project-URL: Homepage, https://www.wittgenbio.com
Project-URL: Documentation, https://www.wittgenbio.com/api/v1/docs
Keywords: bioinformatics,rna-seq,single-cell,deconvolution,cell-type,wittgen,b2sc
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Provides-Extra: pandas
Requires-Dist: pandas>=1.3; extra == "pandas"
Provides-Extra: dev
Requires-Dist: pandas>=1.3; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# wittgen-b2sc

Thin Python client for the **WittGen B2SC API** — submit a bulk RNA-seq job, poll it to
completion, and pull per-sample single-cell type proportions as a dataframe. Built to the
OpenAPI contract at `https://www.wittgenbio.com/api/v1/openapi.json`.

## Install

```bash
pip install wittgen-b2sc            # core
pip install "wittgen-b2sc[pandas]"  # + DataFrame support
```

If that 404s, this build has not been published to PyPI yet — install the wheel we sent you:

```bash
pip install ./wittgen_b2sc-0.1.1-py3-none-any.whl
pip install pandas          # optional, for as_dataframe=True
```

Installing from git requires access to the private platform repo, so it only works for WittGen
staff and partners who have been granted it:

```bash
pip install "wittgen-b2sc[pandas] @ git+ssh://git@github.com/WittGen-Inc/wittgen-b2sc-platform.git#subdirectory=clients/wittgen-b2sc-python"
```

## Authenticate

Create a per-user API key in the WittGen dashboard (it is shown once — store it as a secret).

```python
from wittgen_b2sc import B2SCClient
client = B2SCClient(api_key="wgk_...")
```

## Quickstart

```python
# 1. Submit a job against a built-in reference dataset
job = client.submit_job("breast_cancer_cell_type3", source="reference_dataset")
job_id = job["job_id"]

# 2. Wait for the generative pipeline, then for the R analysis stage
#    (a full run takes ~30 minutes — the GPU generates single cells from your bulk profile)
client.wait_for_completion(job_id, poll_interval=15, timeout=3600, wait_for_report=True)

# 3. Per-sample cell-type proportions as a tidy DataFrame
df = client.get_proportions(job_id, as_dataframe=True)   # columns: sample, cell_type, proportion
print(df.head())

# 4. Ask for the AI clinical report, then wait for the PDF.
#    This step is explicit because it is the most expensive operation in the pipeline —
#    it is not generated unless you ask for it.
client.generate_report(job_id)
client.wait_for_report(job_id)
client.download_report(job_id, "report.pdf")
```

## Databricks quickstart

Run inside a Databricks notebook. Store the key in a **secret scope**, never inline.

```python
# Cell 1 — install
# Until the package is on PyPI, upload the wheel to DBFS and install that instead:
#   %pip install /dbfs/FileStore/wittgen_b2sc-0.1.1-py3-none-any.whl
%pip install "wittgen-b2sc[pandas]"

# Cell 2 — client (key from a Databricks secret scope)
from wittgen_b2sc import B2SCClient
api_key = dbutils.secrets.get(scope="wittgen", key="b2sc_api_key")
client = B2SCClient(api_key=api_key)

# Cell 3 — submit + await + load as a Spark-ready pandas DataFrame
job = client.submit_job("breast_cancer_cell_type3", source="reference_dataset")
client.wait_for_completion(job["job_id"])
pdf = client.get_proportions(job["job_id"], as_dataframe=True)
sdf = spark.createDataFrame(pdf)      # -> a Spark DataFrame you can join/aggregate/save to Delta
sdf.display()
```

## API surface

| Method | Description |
|---|---|
| `list_models()` | Available disease models |
| `submit_job(disease_model, source, input_file_key=None)` | Submit a job → job record |
| `get_job(job_id)` | Current status |
| `wait_for_completion(job_id, poll_interval=15, timeout=3600, wait_for_report=False)` | Poll until COMPLETED (or, with `wait_for_report=True`, until the report is done too) |
| `get_results_data(job_id)` | Aggregated summary (mean proportions across the cohort) + metadata |
| `get_proportions(job_id, fmt="long"\|"wide", as_dataframe=False)` | Per-sample proportions |
| `get_report(job_id)` | Report status + presigned URL |
| `download_report(job_id, dest_path)` | Save the report PDF |

`wait_for_completion` returns as soon as the job is **COMPLETED** (proportions are ready then);
the AI report is generated server-side shortly after — poll `get_report()` for it. Errors raise
`B2SCError` (`.status`, `.code`); a poll timeout raises `B2SCTimeout`. A `409` from
`get_proportions` means the results are not produced yet — retry.

> **Data residency / BAA:** genomic expression data is PHI. Confirm your BAA and the API
> region with WittGen before sending patient-derived data. See the data-residency one-pager.

## License

Apache-2.0 — see [LICENSE](LICENSE). This client SDK is open source; the WittGen B2SC **model
and service** it talks to remain proprietary. Copyright 2026 WittGen Biotechnologies.
