poetry2nix turns Poetry projects into Nix derivations without the need to actually write Nix expressions

Overview

poetry2nix

poetry2nix turns Poetry projects into Nix derivations without the need to actually write Nix expressions. It does so by parsing pyproject.toml and poetry.lock and converting them to Nix derivations on the fly.

For more information, see the announcement post on the Tweag blog. Development of poetry2nix has been supported by Tweag.

API

The poetry2nix public API consists of the following attributes:

  • mkPoetryApplication: Creates a Python application.
  • mkPoetryEnv: Creates a Python environment with an interpreter and all packages from poetry.lock.
  • mkPoetryPackages: Creates an attribute set providing access to the generated packages and other artifacts.
  • mkPoetryScriptsPackage: Creates a package containing the scripts from tool.poetry.scripts of the pyproject.toml.
  • mkPoetryEditablePackage: Creates a package containing editable sources. Changes in the specified paths will be reflected in an interactive nix-shell session without the need to restart it.
  • defaultPoetryOverrides: A set of bundled overrides fixing problems with Python packages.
  • overrides.withDefaults: A convenience function for specifying overrides on top of the defaults.
  • overrides.withoutDefaults: A convenience function for specifying overrides without defaults.
  • cleanPythonSources: A function to create a source filter for python projects.

mkPoetryApplication

Creates a Python application using the Python interpreter specified based on the designated poetry project and lock files. mkPoetryApplication takes an attribute set with the following attributes (attributes without default are mandatory):

  • projectDir: path to the root of the project.
  • src: project source (default: cleanPythonSources { src = projectDir; }).
  • pyproject: path to pyproject.toml (default: projectDir + "/pyproject.toml").
  • poetrylock: poetry.lock file path (default: projectDir + "/poetry.lock").
  • overrides: Python overrides to apply (default: [defaultPoetryOverrides]).
  • meta: application meta data (default: {}).
  • python: The Python interpreter to use (default: pkgs.python3).

Other attributes are passed through to buildPythonApplication.

Example

poetry2nix.mkPoetryApplication {
    projectDir = ./.;
}

See ./pkgs/poetry/default.nix for a working example.

Dependency environment

The resulting derivation also has the passthru attribute dependencyEnv, which is an environment with a python interpreter, all non-development dependencies and your application. This can be used if your application doesn't provide any binaries on its own and instead relies on dependencies binaries to call its modules (as is often the case with celery or gunicorn). For example, if your application defines a CLI for the module admin and a gunicorn app for the module web, a working default.nix would contain

let
    app = poetry2nix.mkPoetryApplication {
        projectDir = ./.;
    };
in app.dependencyEnv

After building this expression, your CLI and app can be called with these commands

$ result/bin/python -m admin
$ result/bin/gunicorn web:app

Note: If you need to perform overrides on the application, use app.dependencyEnv.override { app = app.override { ... }; }. See ./tests/dependency-environment/default.nix for a full example.

mkPoetryEnv

Creates an environment that provides a Python interpreter along with all dependencies declared by the designated poetry project and lock files. Also allows package sources of an application to be installed in editable mode for fast development. mkPoetryEnv takes an attribute set with the following attributes (attributes without default are mandatory):

  • projectDir: path to the root of the project.
  • pyproject: path to pyproject.toml (default: projectDir + "/pyproject.toml").
  • poetrylock: poetry.lock file path (default: projectDir + "/poetry.lock").
  • overrides: Python overrides to apply (default: [defaultPoetryOverrides]).
  • python: The Python interpreter to use (default: pkgs.python3).
  • editablePackageSources: A mapping from package name to source directory, these will be installed in editable mode (default: {}).

Example

poetry2nix.mkPoetryEnv {
    projectDir = ./.;
}

See ./tests/env/default.nix for a working example.

Example with editable packages

poetry2nix.mkPoetryEnv {
    projectDir = ./.;
    editablePackageSources = {
        my-app = ./src;
    };
}

See ./tests/editable/default.nix for a working example of an editable package.

Example shell.nix

The env attribute of the attribute set created by mkPoetryEnv contains a shell environment.

{ pkgs ? import 
    {} }:
let
  myAppEnv = pkgs.poetry2nix.mkPoetryEnv {
    projectDir = ./.;
    editablePackageSources = {
      my-app = ./src;
    };
  };
in myAppEnv.env

Example shell.nix with external dependencies

For a shell environment including external dependencies, override the env to add dependency packages (for example, pkgs.hello) as build inputs.

{ pkgs ? import 
    {} }:
let
  myAppEnv = pkgs.poetry2nix.mkPoetryEnv {
    projectDir = ./.;
    editablePackageSources = {
      my-app = ./src;
    };
  };
in myAppEnv.env.overrideAttrs (oldAttrs: {
  buildInputs = [ pkgs.hello ]:
})

mkPoetryPackages

Creates an attribute set of the shape { python, poetryPackages, pyProject, poetryLock }. Where python is the interpreter specified, poetryPackages is a list of all generated python packages, pyProject is the parsed pyproject.toml and poetryLock is the parsed poetry.lock file. mkPoetryPackages takes an attribute set with the following attributes (attributes without default are mandatory):

  • projectDir: path to the root of the project.
  • pyproject: path to pyproject.toml (default: projectDir + "/pyproject.toml").
  • poetrylock: poetry.lock file path (default: projectDir + "/poetry.lock").
  • overrides: Python overrides to apply (default: [defaultPoetryOverrides]).
  • python: The Python interpreter to use (default: pkgs.python3).
  • editablePackageSources: A mapping from package name to source directory, these will be installed in editable mode (default: {}).

Example

poetry2nix.mkPoetryPackages {
    projectDir = ./.;
    python = python35;
}

mkPoetryScriptsPackage

Creates a package containing the scripts from tool.poetry.scripts of the pyproject.toml:

  • projectDir: path to the root of the project.
  • pyproject: path to pyproject.toml (default: projectDir + "/pyproject.toml").
  • python: The Python interpreter to use (default: pkgs.python3).

Example

poetry2nix.mkPoetryScriptsPackage {
    projectDir = ./.;
    python = python35;
}

mkPoetryEditablePackage

Creates a package containing editable sources. Changes in the specified paths will be reflected in an interactive nix-shell session without the need to restart it:

  • projectDir: path to the root of the project.
  • pyproject: path to pyproject.toml (default: projectDir + "/pyproject.toml").
  • python: The Python interpreter to use (default: pkgs.python3).
  • editablePackageSources: A mapping from package name to source directory, these will be installed in editable mode (default: {}).

Example

poetry2nix.mkPoetryEditablePackage {
    projectDir = ./.;
    python = python35;
    editablePackageSources = {
        my-app = ./src;
    };
}

defaultPoetryOverrides

poetry2nix bundles a set of default overrides that fix problems with various Python packages. These overrides are implemented in overrides.nix.

overrides.withDefaults

Returns a list containing the specified overlay and defaultPoetryOverrides.

Takes an attribute set with the following attributes (attributes without default are mandatory):

  • src: project source directory

Example

poetry2nix.mkPoetryEnv {
    projectDir = ./.;
    overrides = poetry2nix.overrides.withDefaults (self: super: { foo = null; });
}

See ./tests/override-support/default.nix for a working example.

overrides.withoutDefaults

Returns a list containing just the specified overlay, ignoring defaultPoetryOverrides.

Example

poetry2nix.mkPoetryEnv {
    projectDir = ./.;
    overrides = poetry2nix.overrides.withoutDefaults (self: super: { foo = null; });
}

cleanPythonSources

Provides a source filtering mechanism that:

  • Filters gitignore's
  • Filters pycache/pyc files
  • Uses cleanSourceFilter to filter out .git/.hg, .o/.so, editor backup files & nix result symlinks

Example

poetry2nix.cleanPythonSources {
    src = ./.;
}

Creating a custom Poetry2nix instance

Sometimes when it can be convenient to create a custom instance of poetry2nix with a different set of default overrides.

Example

let
  # self & super refers to poetry2nix
  p2nix = poetry2nix.overrideScope' (self: super: {

    # pyself & pysuper refers to python packages
    defaultPoetryOverrides = super.defaultPoetryOverrides.extend (pyself: pysuper: {

      my-custom-pkg = super.my-custom-pkg.overridePythonAttrs (oldAttrs: { });

    });

  });

in
p2nix.mkPoetryApplication {
  projectDir = ./.;
}

or as a nixpkgs overlay:

let
  pkgs = import 
    {
    overlays = [
      # self & super refers to nixpkgs
      (self: super: {

        # p2self & p2super refers to poetry2nix
        poetry2nix = super.poetry2nix.overrideScope' (p2nixself: p2nixsuper: {

          # pyself & pysuper refers to python packages
          defaultPoetryOverrides = p2nixsuper.defaultPoetryOverrides.extend (pyself: pysuper: {

            my-custom-pkg = super.my-custom-pkg.overridePythonAttrs (oldAttrs: { });

          });

        });
      })

    ];
  };

in pkgs.poetry2nix.mkPoetryApplication {
  projectDir = ./.;
}

Using the flake

For the experimental flakes functionality we provide poetry2nix as a flake providing an overlay to use with nixpkgs. Additionally, the flake provides a flake template to quickly start using poetry2nix in a project:

nix flake init --template github:nix-community/poetry2nix

Contributing

Contributions to this project are welcome in the form of GitHub PRs. Please consider the following before creating PRs:

  • This project uses nixpkgs-fmt for formatting the Nix code. You can use nix-shell --run "nixpkgs-fmt ." to format everything.
  • If you are planning to make any considerable changes, you should first present your plans in a GitHub issue so it can be discussed.
  • If you add new features please consider adding tests. You can run them locally as follows:
nix-build --keep-going --show-trace tests/default.nix

License

poetry2nix is released under the terms of the MIT license.

Owner
Nix community projects
A project incubator that works in parallel of the @NixOS org
Nix community projects
The official repository of iGEM Paris Bettencourt team's software tools.

iGEM_ParisBettencourt21 The official repository of iGEM Paris Bettencourt team's software tools. Cell counting There are two programs dedicated to the

Abhay Koushik 1 Oct 21, 2021
A tool for removing PUPs using signatures

Unwanted program removal tool A tool for removing PUPs using signatures What is the unwanted program removal tool? The unwanted program removal tool i

4 Sep 20, 2022
A domonic-like wrapper around selectolax

A domonic-like wrapper around selectolax

byteface 3 Jun 23, 2022
Procedural modeling of fruit and sandstorm in Blender (bpy).

SandFruit Procedural modelling of fruit and sandstorm. Created by Adriana Arcia and Maya Boateng. Last updated December 19, 2020 Goal & Inspiration Ou

Adriana Arcia 2 Mar 20, 2022
Python - Aprendendo Python na ByLearn

PYTHON Identação Escopo Pai Escopo filho Escopo neto Variaveis

Italo Rafael 3 May 31, 2022
An upgraded version of extractJS

extractJS_2.0 An enhanced version of extractJS with even more functionality Features Discover JavaScript files directly from the webpage Customizable

Ali 4 Dec 21, 2022
CountdownTimer - Countdown Timer For Python

Countdown Timer This python script asks for the user time (input) in seconds, an

Arinzechukwu Okoye 1 Jan 01, 2022
Repository for my Monika Assistant project

Monika_Assistant Repository for my Monika Assistant project Major changes: Added face tracker Added manual daily log to see how long it takes me to fi

3 Jan 10, 2022
Run CodeServer on Google Colab using Inlets in less than 60 secs using your own domain.

Inlets Colab Run CodeServer on Colab using Inlets in less than 60 secs using your own domain. Features Optimized for Inlets/InletsPro Use your own Cus

2 Dec 30, 2021
Learn Python Regular Expressions step by step from beginner to advanced levels

Python re(gex)? Learn Python Regular Expressions step by step from beginner to advanced levels with hundreds of examples and exercises The book also i

Sundeep Agarwal 1.3k Dec 28, 2022
This program generates automatically new folders containing old version of program

Automated Folder Versions Generator by Sergiy Grimoldi - V.0.0.2 This program generates automatically new folders containing old version of something

Sergiy Grimoldi 1 Dec 23, 2021
Telop - Encode and decode messages using an interpretation of the telegraphic code devised by José María Mathé

telop Telop (TELégrafoÓPtico) - Utilidad para codificar y descodificar mensajes de texto empleando una interpretación del código telegráfico ideado po

Ricardo F. 4 Nov 01, 2022
Ml-design-patterns - Source code accompanying O'Reilly book: Machine Learning Design Patterns

This is not an official Google product ml-design-patterns Source code accompanying O'Reilly book: Title: Machine Learning Design Patterns Authors: Val

Google Cloud Platform 1.5k Jan 05, 2023
Inverted-pendulum-with-fuzzy-control - Inverted pendulum with fuzzy control

Fuzzy Inverted Pendulum Basically, this project consists of an inverted pendulum

Mahan Ahmadvand 1 Aug 25, 2022
The third home of the bare Programming Language (1st there's my heart, the forest came second and then there's Github :)

The third home of the bare Programming Language (1st there's my heart, the forest came second and then there's Github :)

Garren Souza 7 Dec 24, 2022
Run the Tianxunet software on the Xiaoyao Android simulator

Run the Tianxunet software on the Xiaoyao Android simulator, and automatically fill in the answers of English listening on the premise of having answers

1 Feb 13, 2022
Process RunGap output file of a workout and load data into Apple Numbers Spreadsheet and my website with API calls

BSD 3-Clause License Copyright (c) 2020, Mike Bromberek All rights reserved. ProcessWorkout Exercise data is exported in JSON format to iCloud using

Mike Bromberek 1 Jan 03, 2022
Ergonomic option parser on top of dataclasses, inspired by structopt.

oppapī Ergonomic option parser on top of dataclasses, inspired by structopt. Usage from typing import Optional from oppapi import from_args, oppapi @

yukinarit 4 Jul 19, 2022
Web-based Sudoku solver built using Python. A demonstration of how backtracking works.

Sudoku Solver A web-based Sudoku solver built using Python and Python only The motivation is to demonstrate how Backtracking algorithm works. Some of

Jerry Ng 2 Dec 31, 2022
A tool for checking if the external data used in Flatpak manifests is still up to date

Flatpak External Data Checker This is a tool for checking for outdated or broken links of external data in Flatpak manifests. Motivation Flatpak apps

Flathub 76 Dec 24, 2022