Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions .devcontainer/Dockerfile

This file was deleted.

39 changes: 0 additions & 39 deletions .devcontainer/devcontainer.json

This file was deleted.

2 changes: 1 addition & 1 deletion .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
platform: linux/arm64
build:
context: ../
dockerfile: .devcontainer/Dockerfile
dockerfile: Dockerfile
volumes:
- ../:/home/cbfkit
- ${SSH_KEYS_DIR:-~/.ssh}:/root/.ssh:ro
Expand Down
34 changes: 33 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Keeps the build context small. The Dockerfile does `COPY . .`, so anything
# not excluded here is shipped into the image, and generated animation output
# dwarfs the source tree (examples/ and tutorials/ are ~186 MB on disk but only
# ~736 KB tracked).
#
# README.md and LICENSE must NOT be excluded: setuptools reads both when it
# builds the wheel metadata.

.git
.gitignore
.github

# Python build and cache artefacts
**/__pycache__
**/*.pyc
**/*.pyo
Expand All @@ -8,10 +19,31 @@
**/*.dylib
**/*.o
**/*.swp
**/*.egg-info
build/
dist/
.venv
.env
mypy_cache
.mypy_cache
.pytest_cache
.ruff_cache
.ipynb_checkpoints

# Generated figures, animations and rendered notebooks. Safe to drop: src/
# contains no media, and package-data is limited to codegen/templates/*.j2,
# py.typed and VERSION.
media/
**/*.gif
**/*.mp4
**/*.png
**/*.html

# Prose and local tooling state, not needed to run the library
docs/
paper/
blog/
.omc/
.playwright-mcp/

__MACOSX
.DS_Store
77 changes: 37 additions & 40 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
# Environment Configuration for cbfkit
# =====================================
# Copy this file to .env and uncomment/customize paths for your system.
# If not set, tools will use their default local cache directories.
# Environment configuration for cbfkit
# ====================================
# Copy this file to .env and uncomment what you need.
#
# Scope: .env is loaded by the root conftest.py, which only pytest imports.
# These variables therefore apply to `pytest` runs and nothing else. A plain
# `python tutorials/....py`, and the mypy/ruff/black processes, never read this
# file -- export those in your shell profile instead.

# ============================================
# JAX / GPU CONFIGURATION
# JAX
# ============================================

# Enable 64-bit float precision (recommended for numerical stability)
# Required for QP solvers (OSQP/JAXopt) and MPPI exponential weighting
JAX_ENABLE_X64=true
# Backend selection. conftest.py already defaults the test session to "cpu",
# so set this only to override (for example to exercise a GPU build).
# JAX_PLATFORM_NAME=gpu

# Force JAX to use CPU or GPU backend
# JAX_PLATFORM_NAME=cpu

# GPU memory preallocation (default: true, preallocates 75% of GPU memory)
# Set to false to allocate memory on-demand (may cause fragmentation)
# GPU memory preallocation (default: true, preallocates 75% of GPU memory).
# Set to false to allocate on demand; may cause fragmentation.
# XLA_PYTHON_CLIENT_PREALLOCATE=false

# Fraction of GPU memory to preallocate (default: 0.75)
# Increase if you get OOM errors at startup, decrease if sharing GPU
# Fraction of GPU memory to preallocate (default: 0.75).
# Raise it if you hit OOM at startup, lower it when sharing a GPU.
# XLA_PYTHON_CLIENT_MEM_FRACTION=0.75

# Memory allocator strategy
# Set to "platform" for minimal memory footprint (slower, good for debugging OOM)
# Allocator strategy. "platform" minimises footprint at a speed cost, which
# helps when debugging OOM.
# XLA_PYTHON_CLIENT_ALLOCATOR=platform

# 64-bit precision is enabled in code (src/cbfkit/__init__.py calls
# config.update("jax_enable_x64", True) at import), so JAX_ENABLE_X64 does not
# belong here.

# ============================================
# CACHE DIRECTORIES (for cloud sync users)
# Cache locations
# ============================================
# Uncomment the paths for your operating system:

# --- Windows ---
# PYTHONPYCACHEPREFIX=C:\Users\yourname\.cache\pycache
# MYPY_CACHE_DIR=C:\Users\yourname\.cache\mypy
# PYTEST_CACHE_DIR=C:\Users\yourname\.cache\pytest
# RUFF_CACHE_DIR=C:\Users\yourname\.cache\ruff

# --- macOS ---
# PYTHONPYCACHEPREFIX=/Users/yourname/.cache/pycache
# MYPY_CACHE_DIR=/Users/yourname/.cache/mypy
# PYTEST_CACHE_DIR=/Users/yourname/.cache/pytest
# RUFF_CACHE_DIR=/Users/yourname/.cache/ruff

# --- Linux (Ubuntu, etc.) ---
# PYTHONPYCACHEPREFIX=/home/yourname/.cache/pycache
# MYPY_CACHE_DIR=/home/yourname/.cache/mypy

# Moves pytest's cache, which is useful when the checkout lives in a synced
# folder. Applied by conftest.py::pytest_configure.
# PYTEST_CACHE_DIR=/home/yourname/.cache/pytest
# RUFF_CACHE_DIR=/home/yourname/.cache/ruff

# Virtual environment location (must be set as system env var, not here)
# Windows: UV_PROJECT_ENVIRONMENT=C:\Users\yourname\.venvs\cbfkit
# macOS: UV_PROJECT_ENVIRONMENT=/Users/yourname/.venvs/cbfkit
# Linux: UV_PROJECT_ENVIRONMENT=/home/yourname/.venvs/cbfkit
# The following CANNOT be set from this file, and earlier versions of it were
# wrong to suggest otherwise:
#
# MYPY_CACHE_DIR, RUFF_CACHE_DIR mypy and ruff are separate processes and
# never load .env
# PYTHONPYCACHEPREFIX Python reads it at interpreter startup,
# long before conftest.py runs
# UV_PROJECT_ENVIRONMENT uv reads it before Python starts
#
# Export those in your shell profile, e.g.
# export MYPY_CACHE_DIR="$HOME/.cache/mypy"
Empty file removed .gitattributes
Empty file.
19 changes: 6 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,17 @@ EXPOSE 8888

WORKDIR /home/cbfkit

# # Copy the project files
COPY pyproject.toml ./

# Set the PYTHONPATH to include /home and project directories
ENV PYTHONPATH="/home:/home/cbfkit:/home/cbfkit/src:${PYTHONPATH}"

# Copy dependency definitions first to leverage caching
COPY pyproject.toml uv.lock ./

# Install dependencies using uv (system-wide)
# We use --no-root to install only dependencies defined in pyproject.toml/uv.lock
# This prevents the command from failing due to missing source code
RUN uv pip install --system --no-root .

# Copy the project files
# Copy the source before installing. The version is read from
# src/cbfkit/VERSION via [tool.setuptools.dynamic], and setuptools treats a
# missing VERSION file as a warning rather than an error -- so installing from
# pyproject.toml alone quietly produces an empty cbfkit 0.0.0.
COPY . .

# Install the project itself
# --system is required: uv installs into a virtualenv by default and aborts
# when it cannot find one, which is always the case in this image.
RUN uv pip install --system .

# Source the ROS 2 environment for all users when starting a shell
Expand Down
22 changes: 14 additions & 8 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
"""
Root conftest.py - Loads environment variables from .env file.
Root conftest.py - test-session environment setup.

This module:
1. Uses python-dotenv to load .env file (if present)
2. Sets environment variables for mypy, ruff, pytest, and Python bytecode caches
3. Sets JAX/XLA GPU memory configuration if specified
4. Configures pytest's cache directory dynamically
pytest.ini anchors the rootdir here, so pytest imports this before any test
module. That makes it the earliest available hook for process-wide setup:

Environment variables are only set if not already present in the environment,
allowing system-level overrides.
1. Loads a .env file from the project root via python-dotenv, when both the
file and the package are present. Existing environment variables win.
2. Puts ./src at the front of sys.path, so the checkout is exercised rather
than an unrelated cbfkit sitting in site-packages.
3. Defaults JAX to the CPU backend, which stops sandboxed and CI hosts from
crashing on a Metal/GPU backend that is visible but not usable.
4. Honours PYTEST_CACHE_DIR, for keeping the cache off a synced folder.

Note the reach of step 1: .env only affects code running inside this process.
mypy, ruff and black are separate processes and never see it.
"""

import os
Expand All @@ -23,6 +28,7 @@
def load_dotenv(*_args, **_kwargs):
return False


# Load .env file from project root (won't override existing env vars)
load_dotenv(Path(__file__).parent / ".env")

Expand Down