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.1

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.1
File Size Uploaded
recto-0.1.1.tar.gz 26.0 kB Details

Built distribution (wheel)

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

Total release size: 62.7 kB

Release files / recto-0.1.1.tar.gz

Download URL recto-0.1.1.tar.gz
Size 26.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b088f2daabdf7b05bfc6b3e7cdb1d754f269324e1627eb79233603e33b40502e
BLAKE2b-256 checksum
How to use checksums
42754c8de7624b6a6fcdf0b187741f6b99f4ca93b292d16d7319983fa6cf69fd
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.1-py3-none-any.whl

Download URL recto-0.1.1-py3-none-any.whl
Size 36.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66747f81fefb99fb3ed26df2b799a31a3cc4af25b5a5194386a9eba01d3e456f
BLAKE2b-256 checksum
How to use checksums
f298bc02b2b20dfdfb3bd0fa2928f6a91161b26e9e7a2ee634ebbbd0c28db163
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

0.1.2

2 release files

This release

0.1.1 This release

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