# Integrating Local Binary Extensions with `uv` This guide explains how we packaged the local `pyzed` binary extension (originally from a system installation) so that `uv` can manage it as a project dependency. ## The Problem The ZED SDK installs its Python wrapper (`pyzed`) as a system-level package (often in `/usr/local/lib/...`). It consists of compiled extensions (`.so` or `.sl` files) and Python bindings. `uv` strictly manages virtual environments and dependencies. It cannot directly "see" or import packages from the global system site-packages unless explicitly configured to use system site-packages (which reduces isolation). Furthermore, a raw `.so` file or a bare directory without metadata isn't a valid package source for `uv`. ## The Solution: A Local Package Wrapper To make `pyzed` compatible with `uv`, we wrapped the raw library files into a proper, minimally compliant Python package located at `libs/pyzed_pkg`. ### 1. Directory Structure We organized the files into a standard package layout: ```text libs/pyzed_pkg/ ├── pyproject.toml # Package metadata (CRITICAL) └── pyzed/ # The actual importable package ├── __init__.py ├── sl.cpython-312-x86_64-linux-gnu.so # The compiled extension └── ... ``` ### 2. The Local `pyproject.toml` We created a `pyproject.toml` inside `libs/pyzed_pkg` to tell build tools how to handle the files. Key configuration points: 1. **Build System**: Uses `setuptools` to bundle the files. 2. **Package Discovery**: Explicitly lists `pyzed`. 3. **Package Data**: **Crucially**, configures `setuptools` to include binary files (`*.so`, `*.pyi`) which are usually ignored by default. ```toml [project] name = "pyzed" version = "0.1.0" description = "Wrapper for ZED SDK" requires-python = ">=3.12" dependencies = [] [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" [tool.setuptools] packages = ["pyzed"] # IMPORTANT: Ensure the binary extension is included in the build [tool.setuptools.package-data] pyzed = ["*.so", "*.pyi"] ``` ## Configuring the Main Project In the root `pyproject.toml` of your application, we used **`[tool.uv.sources]`** to redirect the `pyzed` dependency to our local path. ```toml [project] dependencies = [ "pyzed", # Declared as a normal dependency "cupy-cuda12x", "numpy", ] # uv-specific configuration [tool.uv.sources] pyzed = { path = "libs/pyzed_pkg" } ``` ## How `uv` Processes This 1. **Resolution**: When you run `uv sync` or `uv run`, `uv` sees `pyzed` in the dependencies. 2. **Source Lookup**: It checks `tool.uv.sources` and finds the local path `libs/pyzed_pkg`. 3. **Build/Install**: * `uv` treats the directory as a source distribution. * It uses the `build-system` defined in `libs/pyzed_pkg/pyproject.toml` to build a temporary wheel. * This wheel (containing the `.so` file) is installed into the project's virtual environment (`.venv`). This ensures that your application works seamlessly with `import pyzed.sl` while maintaining a clean, isolated, and reproducible environment managed by `uv`.