A level-locked Arabic conversation partner.
waraq/
├── waraq/
│ ├── init.py
│ ├── store.py # schema + retrieval/insert
│ ├── csv_import.py # bulk CSV import
│ └── vocab_cli.py # CLI: add / list
├── tests/
│ └── test_vocab.py
├── data/
│ ├── seed.csv # gitignored
│ └── waraq.db # gitignored
├── pyproject.toml
└── README.md
SQLite database (waraq.db), created automatically on first run at the
path given by --db (defaults to waraq.db in the current directory).
vocab: word, transliteration, gloss, root, part of speech, grammar point,related_to(self-referencing FK, e.g. for broken plurals pointing back to their singular), date learned, source.vocab_tag: join table mapping vocab entries to one or more tags (e.g. scenario tags likeordering-coffee).
Constraints enforced at the DB level:
- Every entry must have a
wordor agrammar_point(or both), enforced via aCHECKconstraint. - Duplicates are rejected via a unique index on
COALESCE(word, grammar_point) + source.
All commands accept --db <path> to point at a different SQLite file
(defaults to waraq.db in the current directory).
python waraq.vocab_cli.py add \
--word "كتاب" \
--translit "kitab" \
--gloss "book" \
--root "k-t-b" \
--pos noun \
--date-learned 2026-09-12 \
--source "Assimil unit 3" \
--tags "ordering-coffee,introducing-yourself"python waraq.vocab_cli.py add \
--grammar-point "negating equational sentences (ma/laysa)" \
--date-learned 2026-09-12 \
--source "teacher notes session 12" \
--tags "introducing-yourself"| Flag | Meaning |
|---|---|
--word |
The word in Arabic script |
--translit |
Transliteration (Latin script) |
--gloss |
English meaning |
--root |
The root letters (e.g. k-t-b) |
--pos |
Part of speech |
--grammar-point |
A grammar rule, when there's no single word to log |
--related-to |
ID of another entry this one is derived from (e.g. a broken plural pointing back to its singular) |
--date-learned |
Defaults to today if omitted |
--source |
Where you learned it (book, lesson, notes) |
--tags |
Comma-separated, no spaces required — e.g. ordering-coffee,introducing-yourself |
Each tag becomes its own row in vocab_tag, so an entry can carry any
number of tags.
python -m waraq.vocab_cli list
python -m waraq.vocab_cli list --tag ordering-coffee
python -m waraq.vocab_cli list -t ordering-coffee
python -m waraq.vocab_cli list --before-date 2026-09-01
python -m waraq.vocab_cli list -t ordering-coffee -b 2026-09-01| Flag | Meaning |
|---|---|
-t, --tag |
Filter to entries carrying this tag |
-b, --before-date |
Filter to entries learned before this date (YYYY-MM-DD) |
Both filters can be combined (intersection). Without either, lists everything in the store, ordered by date learned.
Imports a CSV of vocab entries in a single pass (tested against a seed CSV file).
Tags within a CSV cell are #-delimited (not comma), to avoid clashing
with the CSV's own column delimiter.
pip install -e .
pytestpip install -e . only needs to be run once (or again if pyproject.toml
changes). It makes the waraq package importable so tests/ can reach it.