Skip to content

Commit

Permalink
Merge pull request #1 from reichlab/init_setup
Browse files Browse the repository at this point in the history
Initial setup, porting/adapting model code from flusion-experiments
  • Loading branch information
elray1 authored Nov 7, 2024
2 parents 8f0e6bf + b4ec705 commit b08602e
Show file tree
Hide file tree
Showing 22 changed files with 2,140 additions and 221 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/pythonapp-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ jobs:
- name: lint
run: |
ruff check .
- name: type check
run: |
mypy .
- name: run tests
run: |
pytest
Expand Down
58 changes: 6 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,16 @@
# reichlab-python-template
# idmodels

[REPLACE WITH A DESCRIPTION OF YOUR PROJECT]

A Python template for Reich Lab projects.

This repo contains a Python package with minimal functionality. It serves as a starting point for new projects (it can be selected as the template when creating a new repo in the Reich Lab org).

There as some opinionated choices here (explained below) which people should override as needed. The main goal is to have a consistent starting point to get up and running with a new Python code base.

## Getting started

[REMOVE THIS SECTION AFTER FOLLOWING THE INSTRUCTIONS BELOW]

If you're using this repo as a template for a new project, make the following changes:

1. Rename the `reichlab_python_template` directory (under `src`) to the name of your package (no hyphens!).

2. Replace all instances of `reichlab-python-template` with the name of your repo/project.

3. Replace all instances of `reichlab_python_template` with the name of your package (remember that Python module names cannot contain hyphens).

4. Update [`pyproject.toml`](pyproject.toml). This file is required and will describe several aspects of your project. `pyproject.toml` replaces `setup.py` and is described in detail on [Python's packaging website](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/).

5. Follow the _Setup for local development_ instructions below to ensure that everything works as expected.
A Python module for modeling infectious disease. Currently supports two classes of models:

- gradient boosting quantile regression (`gbqr`)
- seasonal autoregressive integrated models with exogenous covariates (`sarix`)

## Installing and running the package (no development)

To install this package via pip:

```bash
pip install git+[GITHUB LINK TO YOUR REPO]
```

To run it:
```bash
reichlab_python_template
pip install git+https://github.com/reichlab/idmodels.git
```

## Setup for local development
Expand All @@ -58,7 +33,7 @@ Developers will be using a Python virtual environment that:
2. Change to the repo's root directory:

```bash
cd reichlab-python-template
cd idmodels
```

3. Make sure the correct version of Python is currently active, and create a Python virtual environment:
Expand Down Expand Up @@ -106,10 +81,6 @@ Prerequisites:
The "lockfile" for this project is simply an annotated requirements.txt that is generated by [uv](https://github.com/astral-sh/uv) (uv is a replacement for [pip-compile](https://pypi.org/project/pip-tools/), which
could also be used). There's also a requirements-dev.txt file that contains dependencies needed for development (_e.g._, pytest).
While it's possible to use `pip freeze` to generate a detailed lockfile without a third-party tool like `uv`, the output of `pip freeze` doesn't distinguish between direct and indirect dependencies. This distinction probably doesn't matter for a small project, but on a large project, understanding the dependency graph is critical for resolving conflicts.

Additionally, `uv` (and `pip-compile`) are able to use the list of high-level dependencies in `pyproject.toml` to generate a detailed requirements.txt file, which is a good workflow for keeping everything in sync.

To add or remove a project dependency:
1. Add or remove the dependency in the `[dependencies]` section of `pyproject.toml` (or in the `dev` section of `[project.optional-dependencies]`, if it's a development dependency). Don't pin a specific version, since that will make it harder for users to install the package.
Expand All @@ -134,20 +105,3 @@ To add or remove a project dependency:
# a handy sync option that will cleanup unused dependencies
uv pip sync requirements/requirements-dev.txt && python -m pip install -e .
```

## Opinionated notes on Python tooling

[REMOVE THIS SECTION]

The Python ecosystem is overwhelming! Current opinionated preferences, subject to change:

- To install and manage various versions of Python: [pyenv](https://github.com/pyenv/pyenv) + a local .python-version file
- To install Python packages that are available from anywhere on the machine, regardless of which Python environment is activated: [pipx](https://pipx.pypa.io/stable/)
- To create and manage Python virtual environments: [venv](https://docs.python.org/3/library/venv.html).
- It's handy having the environment packages right there in the project directory
- Most third-party tools for managing virtual environments (_e.g._, poetry, PDM, pipenv) do _too much_ and get in the way
- To generate requirements files from `pyproject.toml`: ['uv'](https://github.com/astral-sh/uv?tab=readme-ov-file#getting-started). It's new, but it's orders of magnitude faster than `pip-compile`.
- To install dependencies: uv again (again, mostly due to speed; good old pip is another fine option)
- Logging: [structlog](https://www.structlog.org/en/stable/). Python's built-in logging module is tedious.
- Linting and formatting: [ruff](https://github.com/astral-sh/ruff) because it does both and is fast.
- Pre-commit hooks: [pre-commit](https://pre-commit.com/).
33 changes: 14 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "reichlab-python-template"
description = "Python template for Reich Lab projects"
name = "idmodels"
description = "A Python module for modeling infectious disease."
license = {text = "MIT License"}
readme = "README.md"
requires-python = ">=3.9"
Expand All @@ -11,27 +11,26 @@ classifiers = [
dynamic = ["version"]

dependencies = [
"structlog",
"rich",
"toml"
"iddata @ git+https://github.com/reichlab/iddata",
"lightgbm",
"numpy",
"pandas",
"sarix @ git+https://github.com/elray1/sarix",
"scikit-learn",
"tqdm",
"timeseriesutils @ git+https://github.com/reichlab/timeseriesutils"
]

[project.optional-dependencies]
dev = [
"coverage",
"freezegun",
"mypy",
"pre-commit",
"pytest",
"ruff",
"types-toml",
"ruff"
]

[project.urls]
Repository = "https://github.com/reichlab/reichlab-python-template.git"

[project.entry-points."console_scripts"]
reichlab_python_template = "reichlab_python_template.app:main"
Repository = "https://github.com/reichlab/idmodels.git"

[build-system]
# Minimum requirements for the build system to execute.
Expand All @@ -44,11 +43,7 @@ testpaths = [
]

[tools.setuptools]
packages = ["reichlab_python_template"]

[tool.reichlab_python_template]
# to write json-formatted logs to disk, uncomment the following line specify the file location
# log_file = "/path/to/log/files/rechlab_python_template.log"
packages = ["idmodels"]

[tool.ruff]
line-length = 120
Expand All @@ -61,4 +56,4 @@ inline-quotes = "double"
quote-style = "double"

[tool.setuptools.dynamic]
version = {attr = "reichlab_python_template.__version__"}
version = {attr = "idmodels.__version__"}
Loading

0 comments on commit b08602e

Please sign in to comment.