Skip to main content

recto

CI PyPI Python License

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 four examples (Anglais, Géographie, Vins, Maths, 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.1.2

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.1.2
File Size Uploaded
recto-0.1.2.tar.gz 26.1 kB Details

Built distribution (wheel)

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

Total release size: 62.8 kB

Release files / recto-0.1.2.tar.gz

Download URL recto-0.1.2.tar.gz
Size 26.1 kB
Tags Source
SHA-256 checksum
How to use checksums
bc95aca7799ddfa6f2aa485ec9d660954531062037db361f892436568585f08a
BLAKE2b-256 checksum
How to use checksums
b9e65e192739e1ae2ca5feb1bd3293cfe0f09eb14416cd9bd8cb4f736e7ebeb2
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.1.2-py3-none-any.whl

Download URL recto-0.1.2-py3-none-any.whl
Size 36.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7674c72dfb21e817e8038c307b8b37bea01c5455821638baf0676d5ce807bd8c
BLAKE2b-256 checksum
How to use checksums
b3f28573f17256019ac20dc66db7aeb8c1c17bd070b8373b6d97fdbeb8d9be07
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

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.2 This release

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