pytorial
A Python library for interactive command-line tutorials.
Install
pipx install pytorial
# or
uv tool install pytorial
To run from a clone instead of an installed copy, see
CONTRIBUTING.md.
Usage
The package ships with three built-in tutorials. The first one is a self-guided tour of the tool itself:
tutorial run using-tutorials
The command is installed both as pytorial and as the alias
tutorial. The examples use tutorial because the same spelling also
works when the CLI is embedded as a tutorial subcommand inside a
host application.
Companion tours: tutorial run shell-basics (shell and editor skills)
and tutorial run writing-tutorials (authoring tutorials of your own).
Discover what's available
tutorial list
Pipe the same command into a script to get tab-separated rows instead of the rich table.
Run or resume
tutorial run <id> # start or resume saved progress
tutorial run --restart <id> # discard saved progress and start over
Review past runs
tutorial review <id>
tutorial review <id> --step 2
tutorial review <id> --run-id <run-id>
Trust author-supplied shell code
tutorial run --allow-shell <id>
A tutorial step may declare pre_command, check_command, or
post_command. Those fields run author-supplied shell code, so they are
opt-in: pass --allow-shell only when you trust the tutorial author.
A workspace: cwd tutorial combined with --allow-shell runs that
shell code in your real project directory rather than in a per-run
workspace, so pass both only for tutorials you wrote or trust completely.
Writing tutorials
Take the interactive walkthrough first:
tutorial run writing-tutorials
File format
A tutorial is a single Markdown file beginning with YAML front matter:
---
id: my-tutorial
title: My Tutorial
summary: One-line description shown by `tutorial list`.
---
# First step
```tutorial-step
required_patterns:
- some-command
hint: Try running `some-command`.
```
Step body in Markdown.
- Required front-matter fields:
id,title,summary. - Optional front-matter field:
workspace, eitherfresh(default) orcwd. See "Run in your project directory" below. - Each top-level
# Headingbecomes one step. - A step may begin with a fenced
tutorial-stepYAML block. Recognised fields arerequired_patterns,pre_command,check_command,post_command,hint,edit_file,kind,options, andanswers. - Without
kindoredit_file, a step opens an interactive shell. edit_fileopens a workspace-relative file in$EDITOR, falling back tovim,vi, ornanowhen$EDITORis unset.kind: input,kind: single_select, andkind: multi_selectprompt directly in the CLI instead of opening a shell or editor.inputanswers use the same string-or-{mode, pattern}format asrequired_patterns; select questions use literal option text inoptionsandanswers.- A shell step has the size of the reader's terminal, so program output
wraps differently for different readers. Plain-string patterns ignore
that, because they collapse whitespace, line breaks included. A
regexpattern that spans several words should join them with\s+rather than a literal space. pre_command,check_command, andpost_commandonly run when the reader passes--allow-shell.- Use one YAML string for each shell field. Multi-line shell scripts
should use YAML
|so one bash process sees the whole script and keepscd,export, and shell options across lines. - Do not use YAML
>for shell fields: it folds newlines into spaces and can break shell syntax.
Run in your project directory
A tutorial that scaffolds a workflow in a real project, such as cutting a release or bootstrapping a repository, can ask to run where the reader launched it instead of in a fresh per-run workspace:
---
id: release-checklist
title: Release Checklist
summary: Walk through a release in this project.
workspace: cwd
---
- The CLI prints one line naming the directory before the first step.
- Progress is tracked per directory:
run,--restart, andlistact on the run recorded in the current directory, so the same tutorial in two projects keeps two independent runs. Re-enter the same directory to resume.reviewstill shows the latest run overall; use--run-idto pick another. --restartdoes not clear the directory, so files left by an earlier run are still there. Prefer non-destructivepost_commandcleanup in these tutorials.tutorial developruns a step of such a tutorial in your current directory too, and prints the same line first. Nothing is reset between iterations, so develop an in-place tutorial inside a scratch copy of a project. (The step source you edit along the way stays in a temporary directory, never in your project.)
Share and install
Install a tutorial Markdown file or URL into the user's tutorial directory:
tutorial install path/to/tutorial.md
tutorial install https://example.com/tutorial.md
tutorial install --force path/to/tutorial.md
Use --force to overwrite an installed tutorial with the same id.
The standalone CLI auto-loads installed tutorials alongside the
built-ins.
Load ad hoc
To use a tutorial without installing it, point at the file or directory on the command line:
tutorial list --tutorial-path some/dir
tutorial run --tutorial-path some/dir <id>
--tutorial-path may be repeated and is appended after the built-ins.
Embedding the CLI
The package can be mounted as a subcommand inside another Typer or
argparse application via add_typer_subcommand and
add_argparse_subcommand in src/pytorial/cli.py. Embedded hosts
prepend the using-tutorials lesson before host-specific tutorials, do
not load the user's installed tutorial directory, and hide the
standalone-only install command. using-tutorials is self-contained
for that reason: it refers to no other tutorial and to no verb a host
hides, so a learner can finish it whatever else the host mounts.
Messages that tell the learner what to type next name the command as the
host mounted it (myhost tutorial review <id>), taken from the host's
own parser, so the host passes nothing extra.
Platform support
Shell steps run in a PTY-backed bash session, and pre_command,
check_command and post_command run through bash, so they need a POSIX
system. On native Windows, use WSL.
Hosts do not need any platform logic: the tutorial subcommand is
registered everywhere. Where no POSIX terminal is available,
tutorial --helpandtutorial run --helpsay that shell steps need WSL;tutorial runrefuses a tutorial that has shell steps, or shell hooks that would execute, before it creates a run or workspace, and exits with status 1;tutorial listshowsneeds WSLin place of the progress status for each tutorial thatrunwould refuse;tutorial list,tutorial review, and tutorials made only of question and editor steps keep working.
A host that wants to word its own note can ask
pytorial.posix_terminal_available().
Contributing
For the literate sources, the make build, and the repo layout, see
CONTRIBUTING.md.
Metadata
Release files for pytorial 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytorial-0.10.0.tar.gz | 14.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytorial-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 60.1 kB
Release files / pytorial-0.10.0.tar.gz
| Download URL | pytorial-0.10.0.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a59593de439a4c958ff1d20166769c8b7f6c62d4f1c5102441be250c5e3964d6
|
|
BLAKE2b-256 checksum How to use checksums |
fa2056a5f6cf67b3af842cbb7e87cd434a80b29a6b46b7259837d1eaad24abe3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.14.4 Linux/7.0.0-31-generic
|
Release files / pytorial-0.10.0-py3-none-any.whl
| Download URL | pytorial-0.10.0-py3-none-any.whl |
|---|---|
| Size | 45.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
830672b6bd2236677ec64a0a647ad786f7832606e9fd627ff1cd60103ccdab4c
|
|
BLAKE2b-256 checksum How to use checksums |
92069bda59266c5474efece9e61cdf12e51b4a48c69e55529a685a1e328db9fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.14.4 Linux/7.0.0-31-generic
|