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 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.2.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.2.2
File Size Uploaded
recto-0.2.2.tar.gz 26.3 kB Details

Built distribution (wheel)

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

Total release size: 63.3 kB

Release files / recto-0.2.2.tar.gz

Download URL recto-0.2.2.tar.gz
Size 26.3 kB
Tags Source
SHA-256 checksum
How to use checksums
55fd010b3bff79369a3da568ab14c784d204634dbc2a46e25c8e44235911c3c4
BLAKE2b-256 checksum
How to use checksums
578149175a72903cd8988c04da319f104c2f7d59ae1cc93cd6fd6cf8854512ec
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.2.2-py3-none-any.whl

Download URL recto-0.2.2-py3-none-any.whl
Size 37.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6e0e12c804246d3733ae7f301cd13bfea5de83afb9847e83aaf20af46673f7b8
BLAKE2b-256 checksum
How to use checksums
28c37cad0f2d81703881def9e0d6fca596f69c0675d8bef696f8d50f336ce09a
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

This release

0.2.2 This release

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