Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .binder/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e .[notebook]
8 changes: 0 additions & 8 deletions .bumpversion.cfg

This file was deleted.

31 changes: 22 additions & 9 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,39 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install dependencies
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml', 'requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install build & test dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
pip install build twine
# Install test/dev dependencies (pytest etc.)
pip install -r requirements.txt
# Install the project (will pull runtime deps from pyproject)
pip install .

- name: Run pytest
run: |
pytest
run: pytest -q

- name: Build (sdist & wheel)
run: python -m build

- name: Build and publish
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/')
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
run: twine upload dist/*
45 changes: 24 additions & 21 deletions .github/workflows/run-pytest-on-push-and-all-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,33 @@ on:

jobs:
deploy:

runs-on: ubuntu-latest
# Runs tests on multiple python versions across the range we support
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4 # latest as at March 2024

- name: Set up Python version ${{ matrix.python-version }}
uses: actions/setup-python@v5 # latest as at March 2024
with:
python-version: ${{ matrix.python-version }}

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel
pip install -r requirements.txt

- name: Run pytest
run: |
pytest
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml', 'requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .[notebook] # ensure optional extras still work
pip install -r requirements.txt

- name: Run pytest
run: pytest -q
53 changes: 40 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
FROM python:3.12
FROM python:3.12-slim

# Environment hygiene
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
DEBIAN_FRONTEND=noninteractive

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt .
# System deps (slim image minimal; add build-essential if future compiled deps needed)
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
build-essential \
gfortran \
libopenblas-dev \
pkg-config \
git \
&& rm -rf /var/lib/apt/lists/*

# Copy metadata first for build cache
COPY pyproject.toml README.md ./
COPY requirements.txt ./

# Copy the full source (needed for editable install)
COPY rcpchgrowth rcpchgrowth

# Upgrade pip/setuptools/wheel first
RUN pip install --upgrade pip setuptools wheel

# Install runtime + notebook deps first (ensures wheels pulled before editable wiring)
RUN pip install python-dateutil scipy pandas matplotlib jupyterlab ipykernel

# Install dev/test tools
RUN pip install -r requirements.txt

# Create a virtual environment
RUN python -m venv /app/venv
# Finally perform editable install (should be fast now; minimal build isolation work)
RUN pip install -e . || (echo '--- Editable install failed; running pip debug ---' && python -m pip debug && exit 1)

# Upgrade pip and install the dependencies in the virtual environment
RUN /app/venv/bin/pip install --upgrade pip
RUN /app/venv/bin/pip install -r requirements.txt
# Bring in notebooks only after package install so they are never considered for package discovery
COPY notebooks notebooks

# Copy the rest of the application code
COPY . .
# Expose Jupyter port
EXPOSE 8888

# Set the entrypoint to use the virtual environment's Python interpreter
CMD ["python3"]
# Helpful default: open bash; docker-compose can override with jupyter lab
CMD ["bash"]
89 changes: 87 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,90 @@
# RCPCH Digital Growth Python library
# RCPCHGrowth Python library

Please go to <https://growth.rcpch.ac.uk/products/python-library/> for all documentation
## Calculations for children's measurements against UK and international growth references.

[![PyPI version](https://img.shields.io/pypi/v/rcpchgrowth.svg?style=flat-square&labelColor=%2311a7f2&color=%230d0d58)](https://pypi.org/project/rcpchgrowth/)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg?style=flat-square&labelColor=%2311a7f2&color=%230d0d58)](https://www.gnu.org/licenses/agpl-3.0)
[![Binder](https://img.shields.io/badge/Binder-Launch?style=flat-square&labelColor=%2311a7f2&color=%230d0d58&logo=binder&logoColor=white)](https://mybinder.org/v2/gh/rcpch/rcpchgrowth-python/live?labpath=notebooks%2FQuickstart.ipynb)
[![Codespaces](https://img.shields.io/badge/Codespaces-Open_in_Cloud?style=flat-square&labelColor=%2311a7f2&color=%230d0d58&logo=github&logoColor=white)](https://codespaces.new/rcpch/rcpchgrowth-python?quickstart=1)

Please go to <https://growth.rcpch.ac.uk/products/python-library/> for full documentation.

Issues can be raised here <https://github.com/rcpch/rcpchgrowth-python/issues>

---

## Installation

### Docker

If you want to avoid setting up docker environments, there are shortcut scripts the create a dockerized environment with RCPCHGrowth already installed.

First ensure the folders have the correct permissions:

```bash
chmod +x s/dev
```

To generate a container which will launch the notebooks in a browser and allow local dev ( with hot reload)

```bash
s/dev
```

### Minimal installation (assuming you have a python virtual env setup)

```bash
pip install rcpchgrowth
```

With notebook & package dependencies:

```bash
pip install "rcpchgrowth[notebook]"
```

The `notebook` extra currently pulls in: `pandas`, `matplotlib`, `jupyterlab`, `ipykernel`.

To verify versions inside a Jupyter session:

```python
import rcpchgrowth, pandas as pd, sys
print(rcpchgrowth.__version__, pd.__version__, sys.version)
```

## Example notebooks

Example notebooks live in `notebooks/`:

- `Quickstart.ipynb` – single measurement, small batch, simple plot.
- `ResearchTemplate.ipynb` – structured workflow for batch CSV processing (ages, SDS, centiles, quality flags, export).
- `AdditionalFunctions.ipynb` - exposes some of the date and calculation functions for more in-depth exploration
- `ExperimentalFunctions.ipynb` - exposes functions that are in development and more experimental

## Data handling / privacy

<table>
<tr>
<td width="6" style="background:#2311a7f2;"></td>
<td>
<strong>Data handling & privacy</strong><br>
<strong>Never commit identifiable patient data.</strong><br>
• Keep raw identifiable data outside version control (secure, access‑controlled).<br>
• De‑identify before analysis (remove names, NHS numbers, full DOB; date‑shift if required).<br>
• Do not push raw exports to forks, PRs or gists.<br>
• Use <code>ResearchTemplate.ipynb</code> for generating de‑identified derived outputs.<br>
<em>If in doubt, stop and seek local information governance guidance.</em>
</td>
</tr>
</table>


---

## Contributing

See issues list and please open discussions before large changes.

---

Copyright © Royal College of Paediatrics and Child Health
28 changes: 22 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
version: "3.12"

version: "3.9"
services:
rcpchgrowth-python:
dev:
build: .
container_name: rcpchgrowth-dev
volumes:
- .:/app
working_dir: /app
tty: true # Allocate a pseudo-TTY
stdin_open: true # Keep stdin open
container_name: rcpchgrowth-python
environment:
- PYTHONPATH=/app
ports:
- "8888:8888"
command:
- bash
- -lc
- |
set -e
mkdir -p /app/notebooks
echo '[DEV] Editable install'
pip install -e /app[notebook]
echo '[DEV] Sanity import'
echo '[DEV] Register kernel'
python -m ipykernel install --name rcpchgrowth --display-name 'rcpchgrowth' --sys-prefix
echo '[DEV] Launching JupyterLab'
exec jupyter lab --ip=0.0.0.0 --no-browser --allow-root \
--NotebookApp.token='' --NotebookApp.password='' \
--notebook-dir=/app/notebooks
Loading