Skip to main content

CLI tools for setting up and retiring GitHub-backed course repositories

Project description

course-setup

CLI tools for setting up and retiring GitHub-backed course repositories.

Installation

Install as a uv tool (recommended):

uv tool install course-setup

This makes setup-course, retire-course, unretire-course, and setup-course-config available on your PATH. All four commands support --version, and --help displays the PyPI URL. To upgrade:

uv tool upgrade course-setup

You can also install with pip (pip install course-setup).

Configuration

Generate a starter config file:

setup-course-config

This creates ~/.config/course-setup/config.toml. Open it and fill in your settings:

[github]
token = "ghp_YOUR_TOKEN_HERE"

[paths]
archive = "/path/to/your/archive"
# readme_source = "/path/to/custom/README.md"   # or a URL

[defaults]
notebook_type = "jupyter"   # or "marimo"
Setting Required Description
[github] token Yes GitHub personal access token. Alternatively, set the GITHUB_TOKEN environment variable.
[paths] archive Yes Directory where retired courses are archived.
[paths] readme_source No Local path or URL to a custom README for new courses. Omit to use the bundled default.
[paths] additional_files No List of file/directory paths to copy into every new course (e.g. data files, exercise notebooks).
[defaults] notebook_type No "jupyter" (default) or "marimo".
[defaults] verbose No true or false (default). Sets the default verbosity for setup-course.
[defaults] extras_group No Default dependency group when --extras is not passed (e.g. "python").
[defaults] weekend No "standard" (skip Sat/Sun) or "israeli" (skip Fri/Sat). Default for --skip-weekends/--skip-israeli-weekends.

To regenerate the config file, use setup-course-config --force.

Usage

setup-course — Create a new course repo

setup-course -c Acme -t python-intro
Flag Description
-c, --client Client name (required)
-t, --topic Course topic (required)
-d, --date YYYY-MM override (defaults to current month). Validated: must be a real month, not more than 2 years ahead.
-n, --num-sessions Number of sessions (creates one notebook per session)
--freq Session frequency: daily or weekly (requires -n, defaults to daily)
--first-notebook-date Start date for notebook files (YYYY-MM-DD); defaults to today
--skip-weekends Skip Saturdays and Sundays when scheduling notebooks
--skip-israeli-weekends Skip Fridays and Saturdays when scheduling notebooks
--notebook-type jupyter or marimo (overrides config default)
--extras Dependency groups to add to the course pyproject.toml (see below)
--add-imports Pre-populate notebooks with import statements from --extras groups
-v, --verbose Show detailed output (paths, filenames, dependencies)
--dry-run Preview what would be created without making any changes

Dependency groups

Group Packages
python ipython
data numpy, pandas, xlrd, openpyxl, pyarrow
viz matplotlib, seaborn, plotly
geo geopandas, folium, shapely
db duckdb, sqlalchemy
ml scikit-learn

You can also define custom groups in your config.toml under [extras]. Entries can be package names or references to other groups (built-in or custom):

[extras]
finance = ["yfinance", "pandas-datareader"]
reuven = ["python", "data", "plotly"]   # expands python & data groups + plotly

Example — a Pandas course with Python extras and data/viz packages:

setup-course -c Acme -t pandas --extras python data

This will:

  1. Create a directory and GitHub repo named {client}-{topic}-{YYYY-MM}
  2. Create a notebook per session, named {client}-{topic}-{YYYY-MM-DD} (.ipynb for Jupyter, .py for Marimo)
  3. Generate a pyproject.toml with the notebook dependency and gitautopush
  4. Include a .gitignore for Python, virtual environments, and IDE files
  5. Configure the local .git/config with the GitHub SSH remote
  6. Make an initial commit and push to GitHub
  7. Run uv sync to install all dependencies

By default, a single notebook is created for today's date. Use -n to create multiple notebooks for multi-day or multi-week courses:

setup-course -c Acme -t python-intro -n 5              # 5 daily sessions
setup-course -c Acme -t python-intro -n 5 --freq weekly # 5 weekly sessions

retire-course — Archive a course repo

retire-course ./Acme-python-intro-2026-03
Argument Description
DIRNAME... One or more course directories to retire

This will (for each directory):

  1. Make the GitHub repo private
  2. Move the local directory to your configured archive path under the current year (prompts for confirmation if the year directory doesn't exist)

You can retire multiple courses at once:

retire-course ./Acme-2026-03 ./Beta-2026-03 ./Gamma-2026-02

If any directory fails, the rest are still processed and errors are reported at the end.

unretire-course — Restore a retired course

unretire-course /path/to/archive/2026/Acme-python-intro-2026-03

This will:

  1. Make the GitHub repo public again
  2. Move the directory from the archive back to your current working directory

Live teaching with gitautopush

In a separate terminal, run uv run gitautopush . from inside the course directory. This watches for notebook changes and automatically pushes them to GitHub, so students can follow along in real time by viewing the public repo.

Development

git clone https://github.com/reuven/course-setup.git
cd course-setup
uv sync --dev

Run tests, format, and lint:

uv run pytest
uv run ruff format src/ tests/
uv run ruff check src/ tests/
uv run mypy --strict src/

License

MIT — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

course_setup-2.11.0.tar.gz (33.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

course_setup-2.11.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file course_setup-2.11.0.tar.gz.

File metadata

  • Download URL: course_setup-2.11.0.tar.gz
  • Upload date:
  • Size: 33.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for course_setup-2.11.0.tar.gz
Algorithm Hash digest
SHA256 2d24bcb40725c1a0b1f6c419eefd9c33674d72a63d295fb5572b9513ceb5a3e2
MD5 830ce5735adfb9e67ebfab11b27cf87c
BLAKE2b-256 b98d8903d00c6b664258f641d0c7fd0d9e6d7bbf8e6ac071e545964019b0f22e

See more details on using hashes here.

File details

Details for the file course_setup-2.11.0-py3-none-any.whl.

File metadata

  • Download URL: course_setup-2.11.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for course_setup-2.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d05892216bb3edb5418943e4c5bec229743145bfcc9223d8d3db90bc8fd21083
MD5 f0d5beaa6d5a114dc92cbe2ca13441cd
BLAKE2b-256 4c72ffafbc789aafe5b350486600870ab4f26ea763adcd1f11073626e1d61da6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page