cashmere

cashmere

Nix Flake template for python projects

Description

This is a simple flake on how to configure a project based flake.

Literate Programming Nix Flake

Flake Structure

{

Description

Define the flake's purpose and functionality

description = "Development environment with Python and custom packages";

Inputs

Essential dependencies for the flake.

inputs = {
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  flake-utils.url = "github:numtide/flake-utils";
};

Outputs

Main flake output function.

outputs =
  {
    nixpkgs,
    flake-utils,
    ...
  }:

System Configuration

Multi-system support using flake-utils. Ensuring the flake works on all supported plattforms.

flake-utils.lib.eachDefaultSystem (
  system:
  let
    pkgs = nixpkgs.legacyPackages.${system};

Python Environment

Configure Python version for the project. In this case it is defined to Python version 3.13

python = pkgs.python313;
  1. Custom Python Package Definition

    Create packages for libraries not available in nixpkgs.

    1. Package Configuration

      Define the package metadata and build configuration.

      org-python = python.pkgs.buildPythonPackage rec {
        pname = "org-python";
        version = "0.3.2";
    2. Source Repository

      Fetch source code from upstream repository

      src = pkgs.fetchFromGitHub {
        owner = "honmaple";
        repo = "org-python";
        rev = "v${version}";
      1. Hash Generation

        Generate the required hash for source verification:

        Use nix-prefetch-github for quick hash generation:

        nix-prefetch-github honmaple org-python

        Replace the placeholder hash with the actual value:

          hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
        };
    3. Build System Configuration

      Configure the Python build system

      pyproject = true;
    4. Build Dependencies

      Define packages needed during compilation

      nativeBuildInputs = with python.pkgs; [
        hatchling
        hatch-vcs
      ];
    5. Testing Configuration

      Disable tests to avoid Nix compatibility issues.

      doCheck = false;
    6. Package Metadata

      Provide package information and licensing.

        meta = with pkgs.lib; {
          description = "Python library for reading Emacs org-mode files";
          homepage = "https://github.com/honmaple/org-python";
          license = licenses.bsd3;
          maintainers = [ ];
        };
      };
  2. Development Environment Dependencies

    Define core development tools.

    nativeBuildInputs = [
      python
    ];
  3. Runtime Dependencies

    Specify Python packages and libraries required at runtime

    buildInputs = with python.pkgs; [
      fastapi
      uvicorn
      jinja2
      bcrypt
      python-multipart
      qrcode
      isort
      pyflakes
      org-python
    ];

Output Configuration

Define the flake's outputs and environments

in
{
  1. Development Shell

    Create an interactive development environment.

    devShells.default = pkgs.mkShell {
      inherit nativeBuildInputs;
      buildInputs =
        buildInputs
        ++ (with pkgs; [
          nodejs
          nodePackages.pnpm
          nodePackages.prettier
          black
          sqlite-web
          tailwindcss_4
        ]);
    };
  2. Application Package

    Build the main application package.

        packages.default = python.pkgs.buildPythonApplication {
          pname = "rabatzz";
          version = "0.1.0";
          pyproject = true;
    
          src = ./.;
    
          nativeBuildInputs = with python.pkgs; [
            hatchling
          ];
    
          propagatedBuildInputs = buildInputs;
    
          doCheck = false;
        };
      }
    );

Flake Closure

}

pyproject.toml declaration

build-system

Here we add the hatchling build system, the same as we declared it before in the flake.nix

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

project specification

Here you may define some information about your project, which Python version is required and also its dependencies.

[project]
name = "Example project"
version = "0.1.0"
description = "Example description"
readme = "README.org"
requires-python = ">=3.10"
dependencies = [
    "fastapi",
    "uvicorn[standard]",
    "jinja2"
]

Scripts declaration

When I package my python projects i like to run them in the terminal as any other cli tool. So after packaging if I would run example-project-run then the application would start without the need to run it with the python3 prefix.

[project.scripts]
example-project-run = "src.main:main"

Folder project specification

Last but not least we need to specify the folder, were our package is specified. I like to work with src/ as any other common programming language.

[tool.hatch.build.targets.wheel]
packages = ["src"]