python3Packages.mlflow: build from PyPI wheel, fix server subprocess

This commit is contained in:
gquetel
2026-05-22 11:05:04 +02:00
parent 74b99f7129
commit 0a3aaad743
2 changed files with 37 additions and 16 deletions
@@ -1,10 +1,7 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
# build-system
setuptools,
fetchPypi,
# dependencies
aiohttp,
@@ -31,26 +28,32 @@
buildPythonPackage (finalAttrs: {
pname = "mlflow";
version = "3.12.0";
pyproject = true;
format = "wheel";
__structuredAttrs = true;
src = fetchFromGitHub {
owner = "mlflow";
repo = "mlflow";
tag = "v${finalAttrs.version}";
hash = "sha256-OxhM+KCem0sb9cwtyzrUD/MGfoiiCfgU47qipYRDaFk=";
# We build from the PyPI wheel rather than fetchFromGitHub, because the mlflow-server
# JS UI is absent from GitHub but provided in the wheel.
src = fetchPypi {
pname = "mlflow";
inherit (finalAttrs) version;
format = "wheel";
dist = "py3";
python = "py3";
hash = "sha256-4cKO1MSFV8xSx2bxfxylgmdT3fJB1D8w+ZxF9+prPOA=";
};
# ppyproject.release.toml is the one shipped in the Pypi package, so we use it too.
postPatch = ''
mv pyproject.release.toml pyproject.toml
# Nix-wrapped python populates sys.path via NIX_PYTHONPATH/site hooks,
# but PYTHONPATH stays unset in os.environ. mlflow spawns the server
# in a subprocess with a curated env, so without this patch the child
# interpreter cannot import uvicorn / mlflow itself.
postInstall = ''
patch -p1 -d "$out/lib/python"*/site-packages < ${./subprocess-pythonpath.patch}
'';
build-system = [ setuptools ];
pythonRelaxDeps = [
"cryptography"
];
dependencies = [
aiohttp
alembic
@@ -85,8 +88,12 @@ buildPythonPackage (finalAttrs: {
description = "Open source platform for the machine learning lifecycle";
mainProgram = "mlflow";
homepage = "https://github.com/mlflow/mlflow";
changelog = "https://github.com/mlflow/mlflow/blob/${finalAttrs.src.tag}/CHANGELOG.md";
changelog = "https://github.com/mlflow/mlflow/blob/v${finalAttrs.version}/CHANGELOG.md";
license = lib.licenses.asl20;
# Build from wheel which contains pure Python and pre-built JS bundle.
sourceProvenance = with lib.sourceTypes; [
binaryBytecode
];
maintainers = with lib.maintainers; [
GaetanLepage
];
@@ -0,0 +1,14 @@
--- a/mlflow/server/__init__.py
+++ b/mlflow/server/__init__.py
@@ -471,6 +471,11 @@
else tempfile.mkdtemp()
)
+ # In Nix-packaged environments sys.path is populated by wrappers but
+ # PYTHONPATH is never set in os.environ, so subprocesses (uvicorn,
+ # gunicorn) cannot find packages. Propagate it when not already set.
+ if "PYTHONPATH" not in os.environ:
+ env_map.setdefault("PYTHONPATH", os.pathsep.join(p for p in sys.path if p))
server_proc = _exec_cmd(
full_command,
extra_env=env_map,