diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..7b1e947d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,16 @@ +.git +.github +.venv +venv +__pycache__ +.pytest_cache +.coverage +.coverage.* +htmlcov +build +neuraldbg.egg-info +artifacts +data +models +outputs +*.log diff --git a/.gitignore b/.gitignore index 555b6a67..d6d87164 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,12 @@ venv/ # Generated artifacts artifacts/* !artifacts/.gitkeep +data/* +!data/.gitkeep +models/* +!models/.gitkeep +outputs/* +!outputs/.gitkeep # Private logs and tracking SESSION_SUMMARY.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1eb990ff --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.12-slim + +ENV PIP_NO_CACHE_DIR=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /workspace + +COPY requirements.txt requirements-dev.txt ./ + +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential git && \ + rm -rf /var/lib/apt/lists/* + +RUN python -m pip install --upgrade pip && \ + python -m pip install --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple torch && \ + python -m pip install -r requirements.txt && \ + python -m pip install -r requirements-dev.txt + +COPY . . + +CMD ["bash"] diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..b4c76e6c --- /dev/null +++ b/Makefile @@ -0,0 +1,71 @@ +SHELL := /bin/bash + +PYTHON := $(shell if [ -x .venv/bin/python ]; then echo .venv/bin/python; elif command -v python3 >/dev/null 2>&1; then echo python3; else echo python; fi) +COMPOSE := docker-compose + +.PHONY: help install install-dev up down build rebuild shell test test-docker coverage bandit safety security precommit clean + +help: + @echo "NeuralDBG Make targets:" + @echo " make install - install runtime dependencies" + @echo " make install-dev - install runtime + dev dependencies" + @echo " make build - build Docker dev image" + @echo " make up - start Docker dev service" + @echo " make down - stop Docker dev service" + @echo " make shell - open shell in running dev container" + @echo " make test - run pytest locally" + @echo " make test-docker - run pytest in Docker container" + @echo " make coverage - run coverage with gate >= 60%" + @echo " make bandit - run Bandit security scan" + @echo " make safety - run Safety dependency scan" + @echo " make security - run Bandit + Safety" + @echo " make precommit - run pre-commit hooks on all files" + @echo " make clean - remove local QA artifacts" + +install: + $(PYTHON) -m pip install --upgrade pip + $(PYTHON) -m pip install --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple torch + $(PYTHON) -m pip install -r requirements.txt + +install-dev: install + $(PYTHON) -m pip install -r requirements-dev.txt + +build: + $(COMPOSE) build neuraldbg-dev + +rebuild: + $(COMPOSE) build --no-cache neuraldbg-dev + +up: + $(COMPOSE) up -d + +down: + $(COMPOSE) down + +shell: + $(COMPOSE) exec neuraldbg-dev bash + +test: + $(PYTHON) -m pytest + +test-docker: + $(COMPOSE) run --rm neuraldbg-dev bash -lc "pytest" + +coverage: + $(PYTHON) -m coverage run --source=neuraldbg -m pytest + $(PYTHON) -m coverage report --show-missing --fail-under=60 + +bandit: + $(PYTHON) -m bandit -r . -ll -x tests,*/tests/*,.venv,venv,__pycache__ + +safety: + $(PYTHON) -m safety check --full-report + +security: bandit safety + +precommit: + $(PYTHON) -m pre_commit run --all-files + +clean: + rm -rf .pytest_cache htmlcov .mypy_cache + rm -f .coverage .coverage.* diff --git a/README.md b/README.md index f715aa4f..e9bf2992 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,52 @@ Unlike traditional monitoring tools (TensorBoard, Weights & Biases), NeuralDBG f pip install neuraldbg ``` +### Docker Development (Hermetic Workspace) + +Use Docker to keep a reproducible local environment across machines and contributors. + +```bash +# Build image +docker-compose build + +# Start the dev container (one-command startup) +docker-compose up -d + +# Open a shell in the running workspace +docker-compose exec neuraldbg-dev bash +``` + +Equivalent shortcuts via `Makefile`: + +```bash +make build +make up +make shell +``` + +Run tests inside Docker: + +```bash +docker-compose run --rm neuraldbg-dev bash -lc "pytest" +``` + +Or: + +```bash +make test-docker +``` + +Persistent volumes are mounted to: +- `/data` (host: `./data`) +- `/models` (host: `./models`) +- `/outputs` (host: `./outputs`) + +Stop containers: + +```bash +docker-compose down +``` + ### Basic Usage ```python diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/data/.gitkeep @@ -0,0 +1 @@ + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..dfb126f0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.9" + +services: + neuraldbg-dev: + build: + context: . + dockerfile: Dockerfile + working_dir: /workspace + command: bash -lc "sleep infinity" + tty: true + stdin_open: true + volumes: + - ./:/workspace + - ./data:/data + - ./models:/models + - ./outputs:/outputs diff --git a/models/.gitkeep b/models/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/models/.gitkeep @@ -0,0 +1 @@ + diff --git a/outputs/.gitkeep b/outputs/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/outputs/.gitkeep @@ -0,0 +1 @@ + diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..c0148654 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +pytest>=8.0.0,<9.0.0 +coverage>=7.0.0,<8.0.0 +bandit>=1.7.0,<2.0.0 +safety>=3.0.0,<4.0.0 +pre-commit>=3.0.0,<4.0.0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..bbb79f71 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +numpy>=1.26.0