https://github.com/sciexp/python-nix-template
❄️ (om)nix template for python workspace monorepos +/- pyo3 extension modules with uv2nix and flake-parts 🐍
https://github.com/sciexp/python-nix-template
conda containers devcontainer functional-programming just monorepo nix nix-flake oci pixi pyo3 python python3 railway-oriented-programming runtime-typechecking static-typechecking template-project uv
Last synced: about 2 months ago
JSON representation
❄️ (om)nix template for python workspace monorepos +/- pyo3 extension modules with uv2nix and flake-parts 🐍
- Host: GitHub
- URL: https://github.com/sciexp/python-nix-template
- Owner: sciexp
- License: apache-2.0
- Created: 2025-02-05T18:07:25.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-04-12T07:41:09.000Z (about 2 months ago)
- Last Synced: 2025-04-12T08:34:58.849Z (about 2 months ago)
- Topics: conda, containers, devcontainer, functional-programming, just, monorepo, nix, nix-flake, oci, pixi, pyo3, python, python3, railway-oriented-programming, runtime-typechecking, static-typechecking, template-project, uv
- Language: Nix
- Homepage:
- Size: 482 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
# python-nix-template
A nix template for python packages managed with
[uv2nix](https://github.com/pyproject-nix/uv2nix) and
[flake-parts](https://github.com/hercules-ci/flake-parts). The structure mirrors
those in the [omnix registry](#credits) to the extent possible with python and
its ecosystem.## Template usage
You can use [omnix](https://omnix.page/om/init.html)[^omnix] to initialize this template:
```sh
nix --accept-flake-config run github:juspay/omnix -- \
init github:sciexp/python-nix-template -o new-python-project
```[^omnix]: If you have omnix installed you just need `om init ...` and not `nix run ... -- init`
tl;dr
instantiate a monorepo variant of the template
```sh
nix --accept-flake-config run github:juspay/omnix -- init github:sciexp/python-nix-template -o pnt-mono --non-interactive --params '{
"package-name-kebab-case": "pnt-mono",
"package-name-snake-case": "pnt_mono",
"monorepo-package": true,
"git-org": "pnt-mono",
"author": "Pnt Mono",
"author-email": "[email protected]",
"vscode": true,
"github-ci": true,
"nix-template": false
}' && \
cd pnt-mono && \
git init && \
git commit --allow-empty -m "initial commit (empty)" && \
git add . && \
nix develop --accept-flake-config -c pytest
```You can run `direnv allow` to enter the shell environment that contains
development dependencies or `nix develop --accept-flake-config` to enter (or add
`-c command` to execute individual commands within) the development shell.instantiate a single-package variant of the template
```sh
nix --accept-flake-config run github:juspay/omnix -- init github:sciexp/python-nix-template/main -o pnt-new --non-interactive --params '{
"package-name-kebab-case": "pnt-new",
"package-name-snake-case": "pnt_new",
"monorepo-package": false,
"git-org": "pnt-new",
"author": "Pnt New",
"author-email": "[email protected]",
"vscode": true,
"github-ci": true,
"nix-template": false
}' && \
cd pnt-new && \
git init && \
git commit --allow-empty -m "initial commit (empty)" && \
git add . && \
nix run nixpkgs#uv -- lock && \
nix develop --accept-flake-config -c pytest
```except you may want to update the git ref/rev of the template if you need to pin to a
particular version:- `github:sciexp/python-nix-template/main`
- `github:sciexp/python-nix-template/v0.1.0`
- `github:sciexp/python-nix-template/3289dla`
- `github:sciexp/python-nix-template/devbranch`.### Quick start
#### nix-managed environment
The template supports three types of development environments:
1. nix devshell
2. python virtualenv via uv
3. conda environments via pixiThe intended workflow is to run
```sh
make bootstrap
```only the very first time you are setting up one of these templates. This will
verify you have the [nix package manager](https://nix.dev) and
[direnv](https://direnv.net/) installed. Registration of the repository contents
requires creating a git repository, for example with```sh
git init && git commit --allow-empty -m "initial commit (empty)" && git add .
```but does not require committing.
After this running```sh
direnv allow
```will ensure you have all development tools on a project directory-specific
version of your PATH variable. These include the `just` task runner, which
provides an alternative to using [GNU Make](https://www.gnu.org/software/make/)
as a task runner. See the [task runner](#task-runner) section for a listing of
development commands.You should now be able to run `pytest` or `just test` to confirm the package
tests pass in the devshell environment.> [!WARNING]
> uv recognizes all the packages in the workspace monorepo layout but pixi
> treats each package separately. See [#22](https://github.com/sciexp/python-nix-template/issues/22).If you choose to modify the monorepo packages such as
[packages/pnt-functional](./packages/pnt-functional) then you will need to run
`just uv-lock` to update the [pyproject.toml](./pyproject.toml) and
[uv.lock](./uv.lock) files to include the package and its tests in the
workspace.#### python virtualenv
1. Create and sync virtual environment:
```sh
just venv
source .venv/bin/activate
```2. Run tests:
```sh
just test
```3. Run linting:
```sh
just lint
```4. Build package:
```sh
just build
```## Features
- Modern python packaging with `pyproject.toml`
- Fast dependency management with `uv`
- Reproducible developer environments and builds with `nix` and `uv2nix`
- See the optional monorepo workspace package [pnt-functional](./packages/pnt-functional)
for a brief illustration of functional programming patterns (disabled by default):
- Railway-oriented programming with `expression` for type-safe error handling
- Effect tracking via monad transformers for composable side effects
- Runtime type checking with `beartype` for robust type safety
- Pure functions and immutable data types for reliable code
- Composition of effectful functions using monadic bind operations
- conda ecosystem compatibility via `pixi`## Development
### Prerequisites
If you'd like to develop `python-nix-template` you'll need the [nix package
manager](https://nix.dev). You can optionally make use of
[direnv](https://direnv.net/) to automatically activate the environment. The
project includes a Makefile to help bootstrap your development environment.It provides:
1. Installation of the nix package manager using the Determinate Systems
installer
2. Installation of direnv for automatic environment activation
3. Link to instructions for shell configurationTo get started, run:
```shell
make bootstrap
```Run `make` alone for a listing of available targets.
After nix and direnv are installed, you can either run `direnv allow` or `nix
develop` to enter a [development shell](./nix/modules/devshell.nix) that will
contain necessary system-level dependencies.### Task runner
This project uses [`just`](https://just.systems/man/en/) as a task runner, which
is provided in the [development shell](#prerequisites). List available commands
by running `just` alone.just recipes
```sh
default # List all recipes[CI/CD]
gcloud-context # Set gcloud context
ghsecrets repo="sciexp/python-nix-template" # Update github secrets for repo from environment variables
ghvars repo="sciexp/python-nix-template" # Update github vars for repo from environment variables
pre-commit # Run pre-commit hooks (see pre-commit.nix and note the yaml is git-ignored)[conda package]
conda-build # Package commands (conda)
conda-check # Run all checks in conda environment (lint, type, test)
conda-env # Create and sync conda environment with pixi
conda-lint # Run linting in conda environment with pixi
conda-lint-fix # Run linting and fix errors in conda environment with pixi
conda-lock # Update conda environment
conda-test # Run tests in conda environment with pixi
conda-type # Run type checking in conda environment with pixi
pixi-lock # Update pixi lockfile[nix]
ci # Run CI checks locally with `om ci`
container-build # Build production container image
container-build-dev # Build development container image
container-run # Run production container with port 8888 exposed
container-run-dev # Run development container with port 8888 exposed
dev # Enter the Nix development shell
flake-check # Validate the Nix flake configuration
flake-update # Update all flake inputs to their latest versions[python package]
check # Run all checks (lint, type, test)
lint # Run linting
lint-fix # Run linting and fix errors
test # Run tests
type # Run type checking in uv virtual environment
uv-build # Package commands
uv-lint # Run linting in uv virtual environment
uv-lint-fix # Run linting and fix errors in uv virtual environment
uv-lock # Update lockfile from pyproject.toml
uv-test # Run tests in uv virtual environment
uv-type # Run type checking in uv virtual environment
venv # Sync and enter uv virtual environment[secrets]
check-secrets # Check secrets are available in teller shell.
create-and-populate-separate-secrets path # Complete process: Create and populate separate secrets for each line in the dotenv file
create-and-populate-single-secret name path # Complete process: Create a secret and populate it with the entire contents of a dotenv file
create-secret name # Create a secret with the given name
export # Export unique secrets to dotenv format
get-secret name # Retrieve the contents of a given secret
populate-separate-secrets path # Populate each line of a dotenv-formatted file as a separate secret
populate-single-secret name path # Populate a single secret with the contents of a dotenv-formatted file
seed-dotenv # Create empty dotenv from template
show # Show existing secrets[template]
template-init # Initialize new project from template
template-verify # Verify template functionality by creating and checking a test project
```## credits
### python
- [beartypte/beartype](https://github.com/beartype/beartype)
- [dbrattli/Expression](https://github.com/dbrattli/Expression)### python in nix
- [uv2nix](https://github.com/pyproject-nix/uv2nix)
### nix
See the [omnix registry
flake](https://github.com/juspay/omnix/blob/1.0.0/crates/omnix-init/registry/flake.nix)- [srid/haskell-template](https://github.com/srid/haskell-template)
- [srid/rust-nix-template](https://github.com/srid/rust-nix-template)
- [hercules-ci/flake-parts](https://github.com/hercules-ci/flake-parts)