TNH-Scholar DEV_SETUP¶
This document outlines the standard development environment for TNH‑Scholar. The goals are: clarity, reproducibility, stability, and low onboarding friction.
The project uses pyenv to manage Python versions and Poetry to manage dependencies and virtual environments.
⚠️ Important: Rapid Prototype Phase (0.x)¶
TNH Scholar is in rapid prototype phase. Breaking changes may occur in ANY 0.x release (including patches).
- No backward compatibility guarantees during 0.x
- Breaking changes acceptable in patch releases (0.1.3 → 0.1.4)
- Expect to refactor code when upgrading dependencies
See ADR-PP01: Rapid Prototype Versioning for full policy.
1. Install pyenv (Python version manager)¶
Follow official instructions for your platform:
https://github.com/pyenv/pyenv
Recommended macOS setup (Homebrew):
After installation, ensure your shell is configured:
Reload your shell:
2. Install the required Python version¶
TNH‑Scholar currently targets: Python 3.12.4
Install it with pyenv:
Then set the local version inside the project root:
This ensures all commands inside this directory use that exact Python interpreter.
3. Install Poetry (dependency + project manager)¶
Installation (official method):
Ensure Poetry is added to your PATH (the installer will tell you where to place this):
Verify installation:
4. Configure Poetry for in‑project virtual environments¶
This keeps the .venv/ folder inside the repository, making environment resolution easier for IDEs, Jupyter, and tooling.
5. Create the virtual environment & install project dependencies¶
Inside the project root, the recommended way to create the environment is via the Makefile (see below):
This will:
- Ensure the correct Python version via pyenv.
- Create or reuse the Poetry-managed virtualenv.
- Install all core (non-dev) dependencies from
pyproject.toml.
For development work (tests, linting, docs, Jupyter, etc.), use:
This will:
- Do everything
make setupdoes plus: - Install all dev dependencies (pytest, ruff, ipykernel, etc.).
- Register the
tnh-scholarJupyter kernel.
If you prefer to do it manually without make:
poetry env use python
poetry install # Installs all dependencies including dev group (as of Dec 2025)
poetry run python -m ipykernel install --user --name tnh-scholar --display-name "Python (tnh-scholar)"
Note: As of December 2025, poetry install automatically includes dev dependencies (pytest, mkdocs, mypy, etc.) since the dev group is no longer marked as optional. No need for --with dev flag.
Optional Local-Only Tools: For tools like Sourcery (AI code review), install the optional local group:
This group includes platform-specific tools that may not be available in CI/CD environments and are intentionally excluded from GitHub Actions builds.
6. Common development commands¶
Run the test suite¶
Lint & format¶
Run CLI tools¶
After make pipx-build (recommended for ease of use):
# CLI tools available directly in any shell
audio-transcribe <args>
tnh-gen <args>
ytt-fetch <args>
token-count <args>
# etc.
Without pipx installation (using Poetry environment):
Run any script or tool¶
Example:
7. Makefile¶
The repository includes a Makefile at the project root with development automation:
PYTHON_VERSION = 3.12.4
POETRY = poetry
PIPX = pipx
TNH_CLI_TOOLS = audio-transcribe tnh-gen ytt-fetch nfmt token-count tnh-setup tnh-tree sent-split json-srt srt-translate
# Setup targets
setup:
pyenv install -s $(PYTHON_VERSION)
pyenv local $(PYTHON_VERSION)
$(POETRY) env use python
$(POETRY) install
setup-dev:
pyenv install -s $(PYTHON_VERSION)
pyenv local $(PYTHON_VERSION)
$(POETRY) env use python
$(POETRY) install
$(POETRY) run python -m ipykernel install --user --name tnh-scholar --display-name "Python (tnh-scholar)"
# Build and update targets
build-all:
$(POETRY) self update
$(POETRY) update yt-dlp
$(POETRY) install
$(MAKE) pipx-build
$(MAKE) docs-build
update:
$(POETRY) self update
$(POETRY) update
$(POETRY) install
$(POETRY) build
$(MAKE) pipx-build
# CLI tool installation via pipx (global access)
pipx-build:
@echo "Building pipx install for tnh-scholar (all CLI tools)..."
PIPX_LOG_DIR=$(HOME)/.local/pipx/logs $(PIPX) install --force --editable .
@printf "CLI tools available: audio-transcribe, tnh-gen, ytt-fetch, etc.\n"
# Test and quality targets
test:
$(POETRY) run pytest
lint:
$(POETRY) run ruff check .
format:
$(POETRY) run ruff format .
kernel:
$(POETRY) run python -m ipykernel install --user --name tnh-scholar --display-name "Python (tnh-scholar)"
Common workflows¶
Initial setup:
After pulling changes:
Full rebuild (after major changes):
Install CLI tools globally:
8. Optional: Jupyter kernel registration¶
The recommended way to register the Jupyter kernel is via:
which automatically installs dev dependencies and registers the kernel.
If you need to re-register the kernel manually:
After that, VS Code or Jupyter will show a kernel named Python (tnh-scholar).
9. CI and production recommendations¶
- Commit both
pyproject.tomlandpoetry.lockto version control. - In CI, always install using the lockfile:
- When updating dependencies, update intentionally:
-
Special case: yt-dlp — This package is intentionally unpinned (
>=2025.1.15inpyproject.toml) and should always use the latest version. Runmake build-allto ensure yt-dlp is updated along with Poetry and docs. -
Avoid global packages. Use Poetry environments or
pipxfor global tools.
10. Summary¶
Your workflow should look like this:
- pyenv selects the Python version
- Poetry manages the environment + dependencies
.venv/stays local to the project- All tools run through
poetry run - Lockfile ensures reproducible builds
This combination is stable, clean, and well‑understood—ideal for TNH‑Scholar’s long‑term architecture and multi‑year development cycle.