Skip to content

Commit dacfd8f

Browse files
authored
Update project setup (#72)
* Update `.pre-commit-config.yaml` * Add `.lintr` * Update `pyproject.toml` * Add `.gitattributes` * Add `.envrc` * Update README * Update index page for Jupyter book * Update linting CI * Update Jupyter book CI
1 parent 849aa82 commit dacfd8f

10 files changed

Lines changed: 380 additions & 222 deletions

File tree

.envrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export UV_PROJECT_ENVIRONMENT="$(pwd)/.fancypackage-pyXY"

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SCM syntax highlighting & preventing 3-way merges
2+
pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff

.github/workflows/book.yml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
name: deploy-jupyter-book
22

33
on:
4-
push:
5-
branches:
6-
- main
4+
push:
5+
branches:
6+
- main
77

88
# This job installs dependencies, build the book, and pushes it to `gh-pages`
99
jobs:
10-
deploy-book:
11-
runs-on: ubuntu-latest
12-
steps:
13-
- uses: actions/checkout@v2
10+
deploy-book:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
1414

15-
# Install dependencies
16-
- name: Set up Python 3.10
17-
uses: actions/setup-python@v4
18-
with:
19-
python-version: "3.10"
15+
# Install dependencies
16+
- name: Set up Python 3.14
17+
uses: actions/setup-python@v6
18+
with:
19+
python-version: "3.14"
2020

21-
- name: Install dependencies
22-
run: |
23-
pip install jupyter-book
24-
# Build the book
25-
- name: Build the book
26-
run: |
27-
jupyter-book build notebooks
28-
# Push the book's HTML to github-pages
29-
- name: GitHub Pages action
30-
uses: peaceiris/actions-gh-pages@v4.0.0
31-
with:
32-
github_token: ${{ secrets.GITHUB_TOKEN }}
33-
publish_dir: notebooks/_build/html
21+
- name: Install dependencies
22+
run: |
23+
pip install jupyter-book
24+
25+
- name: Build the book
26+
run: |
27+
jupyter-book build notebooks
28+
29+
- name: GitHub Pages action
30+
uses: peaceiris/actions-gh-pages@v4.0.0
31+
with:
32+
github_token: ${{ secrets.GITHUB_TOKEN }}
33+
publish_dir: notebooks/_build/html

.github/workflows/lint.yml

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
name: Lint
22

33
on:
4-
push:
5-
branches: main
6-
pull_request:
7-
branches: main
4+
push:
5+
branches: main
6+
pull_request:
7+
branches: main
88

99
jobs:
10-
linting:
11-
runs-on: ubuntu-latest
12-
steps:
13-
- uses: actions/checkout@v3
14-
- name: Setup Python 3.10
15-
uses: actions/setup-python@v4
16-
with:
17-
python-version: "3.10"
18-
- name: Install dependencies
19-
run: |
20-
python -m pip install --upgrade pip
21-
pip install pre-commit
22-
- name: Check pre-commit compatibility
23-
run: pre-commit run --all-files --show-diff-on-failure
10+
linting:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout repo
14+
uses: actions/checkout@v6
15+
16+
- name: Setup Python 3.14
17+
uses: actions/setup-python@v6
18+
with:
19+
python-version: "3.14"
20+
21+
- name: Setup R
22+
uses: r-lib/actions/setup-r@v2
23+
with:
24+
r-version: "4.5.3"
25+
use-public-rspm: true
26+
27+
- name: Run pre-commit hooks
28+
uses: pre-commit/action@v3.0.1

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,7 @@ jobs/
160160
*.Rhistory
161161

162162
.vscode/*
163+
164+
# pixi environments
165+
.pixi/*
166+
!.pixi/config.toml

.lintr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
linters: linters_with_defaults(
2+
line_length_linter = line_length_linter(length = 120L),
3+
object_name_linter = NULL
4+
)

.pre-commit-config.yaml

Lines changed: 58 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,63 @@
11
fail_fast: false
22
default_language_version:
3-
python: python3
3+
python: python3
44
default_stages:
5-
- pre-commit
6-
- pre-push
5+
- pre-commit
6+
- pre-push
77
minimum_pre_commit_version: 2.16.0
88
repos:
9-
- repo: https://github.com/mwouts/jupytext
10-
rev: v1.14.5
11-
hooks:
12-
- id: jupytext
13-
args:
14-
[--from, ipynb, --sync, --pipe, black, --pipe-fmt, "py:percent"]
15-
additional_dependencies:
16-
- black==23.1.0 # Matches hook
17-
- repo: https://github.com/psf/black
18-
rev: "23.1.0"
19-
hooks:
20-
- id: black-jupyter
21-
- repo: https://github.com/asottile/blacken-docs
22-
rev: 1.13.0
23-
hooks:
24-
- id: blacken-docs
25-
- repo: https://github.com/PyCQA/isort
26-
rev: 5.12.0
27-
hooks:
28-
- id: isort
29-
- repo: https://github.com/pre-commit/mirrors-prettier
30-
rev: v3.0.0-alpha.4
31-
hooks:
32-
- id: prettier
33-
# Newer versions of node don't work on systems that have an older version of GLIBC
34-
# (in particular Ubuntu 18.04 and Centos 7)
35-
# EOL of Centos 7 is in 2024-06, we can probably get rid of this then.
36-
# See https://github.com/scverse/cookiecutter-scverse/issues/143 and
37-
# https://github.com/jupyterlab/jupyterlab/issues/12675
38-
language_version: "17.9.1"
39-
- repo: https://github.com/charliermarsh/ruff-pre-commit
40-
rev: v0.0.253
41-
hooks:
42-
- id: ruff
43-
args: [--fix, --exit-non-zero-on-fix]
44-
- repo: https://github.com/pre-commit/pre-commit-hooks
45-
rev: v4.4.0
46-
hooks:
47-
- id: detect-private-key
48-
- id: check-ast
49-
- id: end-of-file-fixer
50-
- id: mixed-line-ending
51-
args: [--fix=lf]
52-
- id: trailing-whitespace
53-
- id: check-case-conflict
54-
- repo: local
55-
hooks:
56-
- id: forbid-to-commit
57-
name: Don't commit rej files
58-
entry: |
59-
Cannot commit .rej files. These indicate merge conflicts that arise during automated template updates.
60-
Fix the merge conflicts manually and remove the .rej files.
61-
language: fail
62-
files: '.*\.rej$'
9+
- repo: https://github.com/biomejs/pre-commit
10+
rev: v2.4.12
11+
hooks:
12+
- id: biome-format
13+
exclude: ^\.cruft\.json$ # inconsistent indentation with cruft - file never to be modified manually.
14+
- repo: https://github.com/tox-dev/pyproject-fmt
15+
rev: v2.21.1
16+
hooks:
17+
- id: pyproject-fmt
18+
- repo: https://github.com/astral-sh/ruff-pre-commit
19+
rev: v0.15.11
20+
hooks:
21+
- id: ruff-check
22+
types_or: [python, pyi, jupyter]
23+
args: [--fix, --exit-non-zero-on-fix]
24+
- id: ruff-format
25+
types_or: [python, pyi, jupyter]
26+
- repo: https://github.com/mwouts/jupytext
27+
rev: v1.14.5
28+
hooks:
29+
- id: jupytext
30+
args: [--from, ipynb, --sync, --pipe, "ruff format -", --pipe-fmt, "py:percent"]
31+
additional_dependencies:
32+
- ruff==0.15.11 # Matches hook
33+
- repo: https://github.com/pre-commit/pre-commit-hooks
34+
rev: v6.0.0
35+
hooks:
36+
- id: detect-private-key
37+
- id: check-ast
38+
- id: end-of-file-fixer
39+
- id: mixed-line-ending
40+
args: [--fix=lf]
41+
- id: trailing-whitespace
42+
- id: check-case-conflict
43+
# Check that there are no merge conflicts (could be generated by template sync)
44+
- id: check-merge-conflict
45+
args: [--assume-in-merge]
46+
- repo: https://github.com/lorenzwalthert/precommit
47+
rev: v0.4.3.9021
48+
hooks:
49+
- id: style-files
50+
- id: lintr
51+
- id: parsable-R
52+
- id: no-debug-statement
53+
- id: no-print-statement
54+
- id: no-browser-statement
55+
- repo: local
56+
hooks:
57+
- id: forbid-to-commit
58+
name: Don't commit rej files
59+
entry: |
60+
Cannot commit .rej files. These indicate merge conflicts that arise during automated template updates.
61+
Fix the merge conflicts manually and remove the .rej files.
62+
language: fail
63+
files: '.*\.rej$'

README.md

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
# Single-cell analysis template repository
22

3-
This repository acts as a template notebook for the analysis of single-cell data and methods; the corresponding Jupyter
4-
Book is rendered [here](https://weilerp.github.io/sc_analysis_template/).
5-
You can check the [CellRank 2 reproducibility repository](https://github.com/theislab/cellrank2_reproducibility)
6-
for an example repository following the same outline as this template.
3+
This repository acts as a template notebook for the analysis of single-cell data and methods; the corresponding Jupyter Book is rendered [here](https://weilerp.github.io/sc_analysis_template/).
74

8-
## Set up
5+
You can check out the [CellRank 2](https://github.com/theislab/cellrank2_reproducibility) and [CellRank protocol](https://github.com/theislab/cellrank_protocol) reproducibility repositories for example repositories following the same outline as this template, built off an earlier version of this template repo.
6+
7+
## Project structure
8+
9+
- `data/`
10+
- Directory containing data relevant to project
11+
- Contains one subdirectory for each dataset
12+
- Proposed structure: each dataset has its own subdirectory containing
13+
- `raw/`: original, unaltered data that always exists unless the data has been loaded from an external data directory
14+
- `processed/`: processed data from `raw/`
15+
- `results`: analysis results
16+
- `figures/`
17+
- Directory to collect generated figures
18+
- Contains one subdirectory for each dataset
19+
- `jobs/`
20+
- Directory to collect scripts for submitting HPC jobs, e.g., with sbatch, (in `jobs/scripts/`) and their generated output files (in `jobs/logs/`)
21+
- `notebooks/`
22+
- Directory containing Jupyter notebooks
23+
- Contains one subdirectory for each dataset
24+
- `scripts/`
25+
- Directory containing Python or R scripts
26+
- Contains one subdirectory for each dataset
27+
28+
## Setup
929

1030
1. Rename `src/fancypackage/`.
1131
2. Update `pyproject.toml` to include the correct information
@@ -20,20 +40,64 @@ for an example repository following the same outline as this template.
2040
5. Ensure repository settings are set up correctly to build Jupyter Book:
2141
- In `Settings > Actions > General > Workflow permissions`: Allow read and write permissions.
2242
- In `Settings > Pages > Build and deployment`: Set the branch to `gh-pages`.
43+
6. If you use uv with a custom environment name: update the `UV_PROJECT_ENVIRONMENT` value in `.envrc`
2344

2445
## Installation
2546

47+
### uv
48+
49+
To install the accompanying packages with [uv](https://docs.astral.sh/uv/), you can run
50+
51+
```bash
52+
uv venv
53+
uv sync --group jupyter
54+
uv run pre-commit install
55+
56+
# Optional: Add jupyter kernel
57+
uv run ipython kernel install --user --env VIRTUAL_ENV .venv --name fancypackage --display-name "fancypackage"
58+
```
59+
60+
If you want to specify a custom environment name and specific Python version, you may use [direnv](https://direnv.net/) and run
61+
62+
```bash
63+
direnv allow
64+
uv venv fancypackage-pyXY -p X.Y
65+
uv sync --group jupyter
66+
uv run pre-commit install
67+
68+
# Optional: Add jupyter kernel
69+
uv run ipython kernel install --user --env VIRTUAL_ENV $UV_PROJECT_ENVIRONMENT --name fancypackage-pyXY --display-name "fancypackage-pyX.Y"
70+
```
71+
72+
### pixi
73+
74+
To set up the project with [pixi](https://pixi.prefix.dev/latest/), run
75+
76+
```bash
77+
pixi add --pypi --editable --no-install --frozen "fancypackage @ file://$(pwd)"
78+
pixi install
79+
pixi run setup-pre-commit
80+
81+
# Optional: Add jupyter kernel
82+
pixi run ipython kernel install --user --env ~/.pixi/envs/default --name fancypackage --display-name "fancypackage"
83+
```
84+
85+
and to use a specific Python version and environment name, run
86+
2687
```bash
27-
conda create -n fancyname-pyXX python=X.X --yes && conda activate fancyname-pyXX
28-
pip install -e ".[dev,jupyter]"
29-
pre-commit install
88+
pixi add --frozen --feature pyXY python=X.Y
89+
pixi workspace environment add fancypackage-pyXY --feature pyXY --feature dev --feature jupyter
90+
pixi add --pypi --editable --no-install --frozen "fancypackage @ file://$(pwd)"
91+
pixi install -e fancypackage-pyXY
92+
pixi run setup-pre-commit
3093

31-
python -m ipykernel install --user --name fancyname-pyXX --display-name "fancyname-pyXX"
94+
# Optional: Add jupyter kernel
95+
pixi run ipython kernel install --user --env VIRTUAL_ENV .pixi/envs/fancypackage-pyXY --name fancypackage-pyXY --display-name "fancypackage-pyX.Y"
3296
```
3397

3498
## Things to keep in mind
3599

36-
Whenever you use a new single-cell tool, add it to `known_bio` in `pyproject.toml` s.t. `isort` can work correctly.
100+
Whenever you use a new single-cell tool, add it to `bio` in `pyproject.toml` so `isort` can work correctly.
37101

38102
## Workflow
39103

0 commit comments

Comments
 (0)