I’m trying to package a Django website to get the following:
A Python environment with the dependencies (and the Django website modules) installed
A custom binary manage-myproject, which would set some custom environment variables, and then run the django-admin binary, provided by the Django Python package
An additional Python package, gunicorn, installed in the same Python environment (so that it can run the site with all its dependencies)
My project uses Poetry, and I was able to use poetry2nix to create a Python environment with all the dependencies installed:
Which correctly adds a bin/managepy-myproject file, but it seems it’s not pointing to the correct Python environment, because the resulting ${app.python}/bin/django-admin file doesn’t exist (and indeed, the path of the Python interpreter referenced in the file is a Python environment without any dependency installed).
Anyway, trying to get point 3 to work, I tried using the following to get the gunicorn Python application added to the environment:
But this resulted in the other Python applications (such as django-admin) not being included anymore in the Python environment.
So my questions are:
How can I properly reference the Python interpreter from the Python environment that has all the other packages installed?
How can I add a Python application to an existing Python environment, while keeping all other applications?
How can I get rid of unwanted binaries in bin? I tried adding my package to environment.systemPackages and all of these packages were then in the PATH (I would just like to have managepy-myproject):
Kind of! I ended up creating a NixOS module I’m now using in production. It still lacks some docs but you might find what you’re looking for in the code.
When building your project I’ve noticed all your code ends up in an src package:
❯ ll result/lib/python3.10/site-packages/
dr-xr-xr-x - root 1 Jan 1970 network_inventory-0.1.0.dist-info
dr-xr-xr-x - root 1 Jan 1970 src
This is not what you want, since it would then mean your code should import packages using from src.backups import models for example, instead of from backups import models. You have 2 choices here:
The first is to keep your project structure as-is, and adapt your pyproject.toml file to list all the packages exposed by your project:
[tool.poetry]
name = "network_inventory"
version = "0.1.0"
description = ""
authors = ["Andreas Zweili <andreas@zweili.ch>"]
license = "GPLv3"
packages = [
{ include = "backups", from = "src" },
{ include = "computers", from = "src" },
{ include = "core", from = "src" },
# include your other packages here…
]
The second is to change your directory structure to put everything in a single package under the src/ directory, like so:
packages = [
{ include = "network_inventory", from = "src" }
]
Option 2 is usually what I do, since it prevents clashes with dependencies that might have the same name (eg. users or core are quite common package names that could conflict).
Just for the record.
I unfortunately wasn’t able to get the second way working.
I managed to get the docker build working, however in a very ugly and hacky way but at least it is working.
For the moment it has to be good enough, at least it doesn’t contain all the development dependencies anymore.