| name | python-dependencies |
| description | Manage Python project dependencies using modern tools (uv and pixi). Use this skill when creating new Python projects, adding dependencies, setting up development environments, configuring IDE and agent integration, or working with standalone scripts. Covers: project initialization, dependency installation, environment selection (uv vs pixi), inline script dependencies (PEP 723), and IDE/agent/LSP configuration for pixi projects. |
Python Dependency Management
Modern Python dependency management using uv and pixi. This skill provides guidance on tool selection, project setup, dependency installation, and IDE configuration.
Tool Selection
New Projects: Ask User Preference
When starting a new Python project, ask the user which dependency management system to use:
Recommended question:
"Would you like to use pixi or uv for this project?
- pixi: Recommended for projects with complex system dependencies (GDAL, HDF5, NetCDF, scientific libraries, geospatial tools)
- uv: Recommended for pure Python projects with PyPI-only dependencies"
Existing Projects: Auto-Detect
if [ -f "pixi.toml" ] || grep -q "\[tool.pixi\]" pyproject.toml 2>/dev/null; then
elif [ -f "pyproject.toml" ] || [ -f "uv.lock" ]; then
else
fi
Project Initialization
When starting a new project from scratch, use the appropriate init command based on the chosen tool.
Pixi: Initialize New Project
Recommended: Use pyproject.toml format (unless user explicitly requests pixi.toml)
pixi init --format pyproject
pixi init --format pyproject myproject
cd myproject
pixi init --format pyproject
pixi add python=3.13
What gets created:
pyproject.toml with [tool.pixi.project] section
.gitignore (excludes .pixi/ environment directory)
.gitattributes
- NOTE: Pixi does NOT create example scripts or source files
Initial structure:
myproject/
├── pyproject.toml # Project configuration
├── .gitignore
└── .gitattributes
Minimal setup workflow:
pixi init --format pyproject myproject
cd myproject
pixi add python=3.13
pixi add --feature dev pytest black ruff pyright
pixi install
UV: Initialize New Project
UV offers multiple project types. Choose based on use case:
Simple application (default - recommended for most projects):
uv init
uv init myproject
cd myproject
What gets created:
pyproject.toml (minimal, no build system)
main.py (hello world example)
README.md
.python-version (pins Python version)
To avoid example files, there is NO flag to prevent main.py and README.md creation. You must delete them manually:
uv init myproject
cd myproject
rm main.py README.md
Library project (for packages to distribute on PyPI):
uv init --lib mypackage
cd mypackage
Creates src/ layout with proper package structure and build system.
Packaged application (CLI tools, installable apps):
uv init --package mycli
cd mycli
Creates src/ layout with entry point configuration for console scripts.
Minimal setup workflow for application:
uv init myproject
cd myproject
rm main.py README.md
uv add requests httpx
uv add --dev pytest black ruff
uv sync
Project Initialization Decision Tree
Starting new project from scratch?
│
├─ User chose pixi?
│ └─ Run: pixi init --format pyproject [name]
│ └─ Add Python: pixi add python=3.13
│ └─ Add dev tools: pixi add --feature dev pytest black ruff
│
├─ User chose uv?
│ ├─ Simple app/script?
│ │ └─ Run: uv init [name]
│ │ └─ Optional: rm main.py README.md
│ │
│ ├─ Library for PyPI?
│ │ └─ Run: uv init --lib [name]
│ │
│ └─ CLI tool/installable app?
│ └─ Run: uv init --package [name]
│
└─ User hasn't chosen?
└─ ASK: "Would you like pixi (system deps) or uv (pure Python)?"
Key Differences in Init Behavior
| Feature | Pixi | UV |
|---|
| Config file | pyproject.toml or pixi.toml | pyproject.toml |
| Example code | ❌ None created | ✅ Creates main.py |
| README | ❌ None created | ✅ Creates README.md |
| Python pin | ❌ Must add manually | ✅ Creates .python-version |
| Build system | ❌ Only if needed | Depends on --lib/--package flags |
| Minimal init | ✅ Already minimal | ❌ Must delete files manually |
Post-Initialization Best Practices
For Pixi projects:
- Immediately add Python version:
pixi add python=3.13
- Set up dev feature:
pixi add --feature dev <tools>
- Create
opencode.json for LSP integration
- Run
pixi install to create environments
For UV projects:
- Delete example files if not needed:
rm main.py README.md
- Add dependencies:
uv add <packages>
- Add dev dependencies:
uv add --dev <tools>
- Run
uv sync to create environment
Converting Existing Projects
Add pixi to existing Python project:
pixi init
pixi init --format pyproject
Add uv to existing project:
uv sync
Pixi Projects
Project Structure
Pixi uses features and environments to organize dependencies:
- Features: Named groups of dependencies (similar to dependency groups in pyproject.toml)
- Environments: Combinations of features that create isolated environments
- Default environment: Built from dependencies in
[dependencies] section
Adding Dependencies
pixi add numpy
pixi add --feature dev pytest black ruff
pixi add --feature test pytest pytest-cov
pixi add --pypi polars
pixi add --channel conda-forge gdal
CRITICAL: Use features, NOT --dev flag (which doesn't exist in pixi)
Setting Up Development Environment
Standard pattern for pixi projects:
[dependencies]
python = ">=3.13"
numpy = "*"
[feature.dev.dependencies]
pytest = "*"
black = "*"
ruff = "*"
mypy = "*"
[feature.dev.pypi-dependencies]
pre-commit = "*"
[environments]
default = []
dev = ["dev"]
Add dev dependencies:
pixi add --feature dev pytest black ruff mypy
Creating Environments
pixi install
pixi run --environment dev pytest
pixi run --environment default python script.py
pixi shell --environment dev
Custom Activation Scripts
Pixi supports running custom activation scripts when entering an environment. These scripts should be stored in your repository (NOT in .pixi/, which is transient and not version controlled).
Recommended location: .pixi-scripts/ or scripts/ directory
Configure in pyproject.toml or pixi.toml:
[activation]
scripts = ["scripts/activate.sh"]
Example activation script (scripts/activate.sh):
#!/bin/bash
export DATA_DIR="${PIXI_PROJECT_ROOT}/data"
export CONFIG_PATH="${PIXI_PROJECT_ROOT}/config.yaml"
export PATH="${PIXI_PROJECT_ROOT}/bin:${PATH}"
echo "✓ Project environment configured"
Key points:
- Scripts run when entering environment via
pixi shell or pixi run
- Use
$PIXI_PROJECT_ROOT to reference project root directory
- Scripts are version controlled (unlike
.pixi/ directory)
- Can set environment variables, configure paths, or run initialization tasks
OpenCode LSP Integration for Pixi
When using pixi projects with OpenCode, configure LSP servers to run inside the pixi environment. This ensures type checking, linting, and other language features use the correct Python interpreter and installed packages.
Create opencode.json in project root:
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"pyright": {
"command": ["pixi", "run", "--environment", "dev", "pyright-langserver", "--stdio"],
"extensions": [".py", ".pyi"]
},
"ruff": {
"command": ["pixi", "run", "--environment", "dev", "ruff", "server"],
"extensions": [".py", ".pyi"]
}
}
}
Key points:
- LSP servers run via
pixi run --environment dev to use the dev environment
- Install LSP tools in the
dev feature (not default environment)
- OpenCode automatically starts LSP servers when opening Python files
- Multiple LSP servers can run simultaneously (pyright for type checking, ruff for linting)
Full setup workflow:
pixi init --format pyproject
pixi add python=3.13 numpy polars
pixi add --feature dev pyright ruff-lsp
pixi install
Alternative: Using basedpyright
For projects preferring basedpyright over pyright:
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"basedpyright": {
"command": ["pixi", "run", "--environment", "dev", "basedpyright-langserver", "--stdio"],
"extensions": [".py", ".pyi"]
}
}
}
pixi add --feature dev basedpyright
UV Projects
Adding Dependencies
uv add numpy
uv add --dev pytest black ruff
uv add "polars>=1.0,<2.0"
uv add --optional docs sphinx sphinx-rtd-theme
Installing Dependencies
uv sync
uv sync --dev
uv sync --group docs
Running Commands
uv run python script.py
uv run pytest
uv run --no-project python script.py
Standalone Scripts with Inline Dependencies
For one-off scripts and tools, use uv with PEP 723 inline script metadata.
Basic Pattern
import requests
from rich import print
response = requests.get("https://api.github.com")
print(response.json())
When to Use Inline Scripts
Use inline script dependencies for:
- One-off automation scripts
- Utility tools
- Quick prototypes
- Scripts shared with colleagues
- CLI tools that should "just work"
Don't use for:
- Large projects with multiple files
- Libraries you'll distribute on PyPI
- Projects with complex build requirements
Creating Inline Scripts
uv add --script myscript.py requests rich
Running Inline Scripts
uv run myscript.py
chmod +x myscript.py
./myscript.py
uv lock --script myscript.py
Shebang Pattern
import typer
import httpx
app = typer.Typer()
@app.command()
def fetch(url: str):
"""Fetch and display URL content."""
response = httpx.get(url)
print(response.text)
if __name__ == "__main__":
app()
Make executable: chmod +x script.py
Run directly: ./script.py https://example.com
Critical Rules
- NEVER modify pyproject.toml or pixi.toml directly - Always use
pixi add or uv add
- NEVER install globally - No
pip install, pip install --user, or sudo pip install
- NO pip fallback - If pixi/uv unavailable, ask user how to proceed
- Pixi features, not --dev - Use
pixi add --feature dev, NOT pixi add --dev
- Always detect project type - Check for pixi.toml or pyproject.toml before installing
- Configure OpenCode for pixi - Create opencode.json to run LSP servers in pixi environment
Decision Tree
User wants to add dependency
│
├─ Is this a standalone script?
│ └─ YES → Use uv inline script metadata (PEP 723)
│
├─ Does pixi.toml exist?
│ └─ YES → Use pixi add [--feature NAME]
│
├─ Does [tool.pixi] exist in pyproject.toml?
│ └─ YES → Use pixi add [--feature NAME]
│
├─ Does pyproject.toml or uv.lock exist?
│ └─ YES → Use uv add [--dev]
│
└─ New project?
└─ ASK: "Would you like pixi (system deps) or uv (pure Python)?"
Common Workflows
Starting a New Pixi Project
pixi init --format pyproject
pixi add python=3.13
pixi add --feature dev pytest black ruff mypy
cat > .vscode/settings.json << 'EOF'
{
"python.defaultInterpreterPath": "${workspaceFolder}/.pixi/envs/dev/bin/python",
"ruff.path": ["${workspaceFolder}/.pixi/envs/dev/bin/ruff"]
}
EOF
pixi install
Starting a New UV Project
uv init myproject
cd myproject
uv add numpy polars
uv add --dev pytest black ruff mypy
uv sync
uv run python -c "import numpy; print(numpy.__version__)"
Converting Requirements.txt to Pixi
while read package; do
pixi add "$package"
done < requirements.txt
Converting Requirements.txt to UV
uv add $(cat requirements.txt)
uv add --dev $(cat requirements-dev.txt)
Error Handling
Tool Not Available
If pixi or uv is not installed:
which pixi
echo "I need to install dependencies but [pixi/uv] is not available."
echo "How would you like me to proceed?"
echo "Options:"
echo " 1. Install pixi: curl -fsSL https://pixi.sh/install.sh | bash"
echo " 2. Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh"
echo " 3. Use a different approach"
DO NOT automatically fall back to pip.
Pixi Environment Not Found
pixi install
pixi install --environment dev
Examples
Example 1: Geospatial Project (Pixi)
pixi init --format pyproject
pixi add python=3.13 gdal geopandas rasterio shapely
pixi add --feature dev pytest black ruff pyright
pixi add --pypi polars
cat > opencode.json << 'EOF'
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"pyright": {
"command": ["pixi", "run", "--environment", "dev", "pyright-langserver", "--stdio"],
"extensions": [".py", ".pyi"]
},
"ruff": {
"command": ["pixi", "run", "--environment", "dev", "ruff", "server"],
"extensions": [".py", ".pyi"]
}
}
}
EOF
pixi install
Example 2: Pure Python Web API (UV)
uv init web-api
cd web-api
uv add fastapi uvicorn pydantic
uv add --dev pytest httpx black ruff
uv sync
uv run uvicorn main:app --reload
Example 3: Quick Data Processing Script
import polars as pl
import sys
df = pl.read_csv(sys.argv[1])
result = df.group_by("category").agg(pl.col("value").mean())
result.write_csv("output.csv")
print(f"Processed {len(df)} rows → {len(result)} categories")
chmod +x process.py
./process.py data.csv
Checking Installed Packages
Pixi
pixi list
pixi list --environment dev
pixi info
UV
uv pip list
uv tree
uv pip show numpy
When NOT to Use This Skill
- Installing system packages (use apt, brew, etc.)
- Managing non-Python dependencies
- Docker container setup (different workflow)
- Installing Python interpreters (use pyenv or uv python install)
- Global tool installation (use uvx or pixi global)