Metadata-Version: 2.4
Name: cisbp
Version: 0.1.0
Summary: Offline-first CLI for versioned CIS-BP transcription factor motif data
Author-email: Jordao Bragantini <jordao.bragantini@czbiohub.org>
Classifier: Operating System :: POSIX
Requires-Python: >=3.12
Requires-Dist: duckdb>=1.4
Requires-Dist: remotezip>=0.12
Requires-Dist: requests>=2.32
Description-Content-Type: text/markdown

# cisbp

`cisbp` is an offline-first command-line client for the [Catalog of Inferred
Sequence Binding Preferences (CIS-BP)](https://cisbp.ccbr.utoronto.ca/). It
downloads a versioned core snapshot once, builds a local DuckDB database, and
then answers TF and motif queries without contacting the website.

The initial release supports CIS-BP build 3.10 and includes:

- 392,337 transcription factors;
- direct, inferred, missing, and unclassified motif-evidence status;
- TF-to-motif associations and source metadata;
- 13,030 motif records, including explicit unavailable matrices; and
- 11,574 public non-empty A/C/G/T matrices.

## Install and run

This project uses [uv](https://docs.astral.sh/uv/):

```bash
uv sync
uv run cisbp --help
```

A query automatically downloads and builds the database if it is not cached:

```bash
uv run cisbp tf search gata4 --species Danio_rerio
```

To download explicitly:

```bash
uv run cisbp data download
uv run cisbp data status
```

The core download transfers approximately 13 MB. The resulting archives and
DuckDB database occupy approximately 112 MB. The downloader uses HTTP range
requests to retrieve only the 6.7 MB core TF-information member from the much
larger CIS-BP metadata archive.

## Commands

Search TF names, CIS-BP IDs, or external IDs:

```bash
cisbp tf search GATA4 --species Homo_sapiens --evidence direct
cisbp tf search 'gata*' --species Danio_rerio --format json
```

Resolve and inspect one TF. A name must be disambiguated with `--species` when
it occurs in multiple organisms:

```bash
cisbp tf get T192662_3.10 --format json
cisbp tf get gata4 --species Danio_rerio
```

Inspect a matrix or its TF associations:

```bash
cisbp motif get M00870_3.10
cisbp motif get M00870_3.10 --format cisbp
cisbp motif associations M00870_3.10 --format json
```

Exit statuses distinguish common query outcomes:

| Status | Meaning |
|---:|---|
| 0 | Success |
| 1 | Download, cache, schema, or database error |
| 3 | No match or no public matrix |
| 4 | Ambiguous exact TF lookup |

## Cache

The default location is:

```text
$XDG_CACHE_HOME/cisbp/
```

or `~/.cache/cisbp/` when `XDG_CACHE_HOME` is unset. Override it with either:

```bash
export CISBP_CACHE_DIR=/path/to/cache
cisbp --cache-dir /another/path data status
```

Each supported content revision is stored under `builds/<version>/`. The
manifest records its source URLs, cache creation time, available HTTP metadata,
sizes, and SHA-256 hashes. Downloads and database construction use a process
lock and atomic file replacement. Source hashes are pinned because CIS-BP can
update files beneath an unchanged build URL; accepting new content therefore
requires an explicit adapter revision rather than silently changing results.

If a database or manifest is missing or invalid, the CLI rebuilds it from valid
cached archives before contacting CIS-BP. There is intentionally no destructive
force-refresh command in the initial release.

## Machine-readable output

Query commands support `--format json`. Results are wrapped with the local
schema version, CIS-BP build, and cache creation time:

```json
{
  "schema_version": 1,
  "cisbp_build": "3.10",
  "retrieved_at": "...",
  "result": []
}
```

Tabular searches and associations also support `--format tsv`. Exact JSON
lookups report expected failures using the same envelope plus an `error` object:

```json
{
  "schema_version": 1,
  "cisbp_build": "3.10",
  "retrieved_at": "...",
  "result": null,
  "error": {"code": "not_found", "message": "..."}
}
```

## Scientific interpretation

- `direct` means CIS-BP associates the TF with an experimentally determined
  motif.
- `inferred` means CIS-BP transferred a motif using its family-specific
  similarity procedure.
- `none` means the source status is `N` and the downloaded core row has no
  motif association.
- `unknown` preserves a motif association that CIS-BP did not classify as
  direct or inferred. Build 3.10 currently contains one such internally
  inconsistent source record; the CLI does not guess its evidence type.
- A motif can be associated with many direct and inferred TFs.
- Some source motifs, notably restricted records described by the CIS-BP FAQ,
  have an association but no public matrix. These are retained with
  `matrix_available = false`.
- The downloaded matrix rows contain raw A/C/G/T frequency or probability
  values. The CLI does not silently convert them into log-odds scoring
  matrices.

CIS-BP asks users to cite its 2014 database paper and the 2019 similarity
regression paper. See the official [citation
page](https://cisbp.ccbr.utoronto.ca/cite.php) and
[FAQ](https://cisbp.ccbr.utoronto.ca/faq.html).

## Network behavior and data redistribution

The CLI performs targeted requests only to the versioned bulk-download files;
it does not scrape CIS-BP search results, TF pages, carts, or undocumented PHP
endpoints. The downloaded data remain in the user's cache and are not bundled
with this package. CIS-BP describes the database as freely available, but
upstream motif sources may impose additional conditions, so do not redistribute
the cached snapshot without checking the applicable terms.

## Development

```bash
uv run ruff format --check .
uv run ruff check .
uv run pytest
uvx ty check src tests
uv build
```

Network downloads are not required by the unit tests. The first real query or
`data download` is the integration test against the supported bulk snapshot.

The current cache lock uses the POSIX `fcntl` interface, so this initial release
supports Linux and macOS. Windows support is deferred until it is needed.
