mirror of
https://github.com/exo-explore/exo.git
synced 2026-01-30 16:51:02 -05:00
Add uv2nix to build Python packages from uv.lock. This creates a fully Nix-managed Python environment with the Rust bindings injected via overlay. Changes: - Add pyproject-nix, uv2nix, and pyproject-build-systems flake inputs - Create python/parts.nix with overlays to inject Nix-built Rust wheel - Export packages.exo on macOS (wraps exo/exo-master/exo-worker with dashboard) - Add checks.lint (ruff, all platforms) and checks.pytest (macOS only) - Simplify CI typecheck job using nicknovitski/nix-develop action - Delete .github/actions/typecheck composite action (no longer needed) - Add no-build-package for MLX packages in pyproject.toml (use wheels) The Python build is currently macOS-only since MLX requires Metal. Linux support will be added once the pyproject dependencies are simplified. Test plan: - Run `nix flake check` on macOS to verify pytest and lint pass - Build exo package on macOS: `nix build .#exo` - Verify CI pipeline passes with simplified typecheck job
94 lines
2.9 KiB
Nix
94 lines
2.9 KiB
Nix
{ inputs, ... }:
|
|
{
|
|
perSystem =
|
|
{ config, self', pkgs, lib, system, ... }:
|
|
let
|
|
# Load workspace from uv.lock
|
|
workspace = inputs.uv2nix.lib.workspace.loadWorkspace {
|
|
workspaceRoot = inputs.self;
|
|
};
|
|
|
|
# Create overlay from workspace
|
|
# Use wheels from PyPI for most packages; we override mlx with our pure Nix Metal build
|
|
overlay = workspace.mkPyprojectOverlay { sourcePreference = "wheel"; };
|
|
|
|
# Override overlay to inject Nix-built components
|
|
exoOverlay = final: prev: {
|
|
# Replace workspace exo_pyo3_bindings with Nix-built wheel
|
|
exo-pyo3-bindings = pkgs.stdenv.mkDerivation {
|
|
pname = "exo-pyo3-bindings";
|
|
version = "0.1.0";
|
|
src = self'.packages.exo_pyo3_bindings;
|
|
# Install from pre-built wheel
|
|
nativeBuildInputs = [ final.pyprojectWheelHook ];
|
|
dontStrip = true;
|
|
};
|
|
};
|
|
|
|
python = pkgs.python313;
|
|
|
|
# Overlay to provide build systems and custom packages
|
|
buildSystemsOverlay = final: prev: {
|
|
# Use our pure Nix-built MLX with Metal support
|
|
mlx = self'.packages.mlx;
|
|
|
|
# mlx-lm is a git dependency that needs setuptools
|
|
mlx-lm = prev.mlx-lm.overrideAttrs (old: {
|
|
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [
|
|
final.setuptools
|
|
];
|
|
});
|
|
};
|
|
|
|
pythonSet = (pkgs.callPackage inputs.pyproject-nix.build.packages {
|
|
inherit python;
|
|
}).overrideScope (
|
|
lib.composeManyExtensions [
|
|
inputs.pyproject-build-systems.overlays.default
|
|
overlay
|
|
exoOverlay
|
|
buildSystemsOverlay
|
|
]
|
|
);
|
|
exoVenv = pythonSet.mkVirtualEnv "exo-env" workspace.deps.default;
|
|
|
|
# Virtual environment with dev dependencies for testing
|
|
testVenv = pythonSet.mkVirtualEnv "exo-test-env" (
|
|
workspace.deps.default // {
|
|
exo = [ "dev" ]; # Include pytest, pytest-asyncio, pytest-env
|
|
}
|
|
);
|
|
|
|
exoPackage = pkgs.runCommand "exo"
|
|
{
|
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
|
}
|
|
''
|
|
mkdir -p $out/bin
|
|
|
|
# Create wrapper scripts
|
|
for script in exo exo-master exo-worker; do
|
|
makeWrapper ${exoVenv}/bin/$script $out/bin/$script \
|
|
--set DASHBOARD_DIR ${self'.packages.dashboard}
|
|
done
|
|
'';
|
|
in
|
|
{
|
|
# Python package only available on macOS (requires MLX/Metal)
|
|
packages = lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin {
|
|
exo = exoPackage;
|
|
# Test environment for running pytest outside of Nix sandbox (needs GPU access)
|
|
exo-test-env = testVenv;
|
|
};
|
|
|
|
checks = {
|
|
# Ruff linting (works on all platforms)
|
|
lint = pkgs.runCommand "ruff-lint" { } ''
|
|
export RUFF_CACHE_DIR="$TMPDIR/ruff-cache"
|
|
${pkgs.ruff}/bin/ruff check ${inputs.self}/
|
|
touch $out
|
|
'';
|
|
};
|
|
};
|
|
}
|