Skip to main content

recto

CI PyPI Python License uv Ruff ty

A terminal app, in the spirit of Anki, to learn things by heart with flashcards.

A deck holds only question/answer pairs. When it is imported, a model writes variants of every card: the question asked the other way round when that makes sense, and a few rephrasings. Each review asks one variant at random, so you learn the knowledge, not one wording. You type the answer, the model scores it and says what was missing, and FSRS decides when the card comes back.

Install

uv tool install recto

Each tagged version is published on PyPI and has its wheel attached to a GitHub release.

Use

export OPENAI_API_KEY=...
recto

Press i to import a deck: one of the five examples (Anglais, Géographie, Vins, Maths, Histoire de France, 50 cards each) or your own TOML file. Then pick a deck and press enter to review, or c to browse its cards: pick one to see its variants, where you can add, edit, delete or generate more.

Variable Default
OPENAI_API_KEY Required: recto won't start without it
RECTO_MODEL gpt-5.4-mini Any OpenAI model name
RECTO_DB the user data directory Where reviews and variants are kept

Write a deck

[deck]
name = "Vins"
description = "Cépages, appellations et régions viticoles françaises"
instructions = "Sois exigeant sur les appellations, tolérant sur l'orthographe des cépages."

[[cards]]
id = "chablis-cepage"
question = "Quel cépage domine les vins blancs de Chablis ?"
answer = "Chardonnay"

The file name is the deck id: importing vins.toml again updates the same deck. instructions is optional and is given to the model when it writes variants and grades answers. Each card needs an id, unique in the deck. Fixing a typo in a question keeps the card's history and regenerates its variants; changing its id starts it over. Cards removed from the file are removed from the deck.

How the code is organized

src/recto/
  domain/      cards, variants, grades, FSRS memory, today's cards, what a re-import changes
  ports/       what the app needs from outside: a deck repository, a variant generator, an answer judge, a clock
  use_cases/   one class per action: import a deck, list decks, next card, submit an answer, manage variants
  adapters/    SQLite, PydanticAI, the TOML deck files, the system clock, an in-memory repository
  tui/         Textual screens, calling use cases only
  decks/       the four example decks
  container.py the one place where adapters are plugged into ports

Develop

make install
cp .example.env .env   # then put your OpenAI key in .env, which git ignores
make run
make check

make help lists the other targets. Tests use fakes, never mocks: use cases run on an in-memory repository, a fake generator, a fake judge and a fixed clock, and the TUI tests drive the real app headless through Textual's Pilot. The SQLite repository is tested against a real database file.

Release

Every push builds the wheel in CI. Pushing a tag on a commit of main that matches the version in pyproject.toml publishes it on PyPI, through trusted publishing, and as a GitHub release:

uv version --bump minor
git commit -am "chore(release): 0.2.0"
git tag v0.2.0
git push origin main v0.2.0

Metadata

Release files for recto 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for recto 0.3.0
File Size Uploaded
recto-0.3.0.tar.gz 28.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for recto 0.3.0
File Interpreter ABI Platform
recto-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 68.4 kB

Release files / recto-0.3.0.tar.gz

Download URL recto-0.3.0.tar.gz
Size 28.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d9cd4805b92fe064e7c26a8ed96ca9d9310967aee58f9489a461496cb05ac71b
BLAKE2b-256 checksum
How to use checksums
0e8d9dfdab247922ed914bab6f00d6ebfa694ee8ab2831f5250ae90ee053e6bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / recto-0.3.0-py3-none-any.whl

Download URL recto-0.3.0-py3-none-any.whl
Size 39.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b02974b90b0b8c0fa560a15bf68d4503c159c88916920548e4f04f16b94802f7
BLAKE2b-256 checksum
How to use checksums
66343f9d82b1d38729cb3e7037e2d9085aa4eeb21bcee0fb1f1b1179eac2b688
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page