kamus
A command-line tool for looking up, searching, and exporting the Kamus Dewan Malay dictionary dataset (converted from PDF to JSON, ~52,212 entries).
Data source & schema
The dataset is a flat JSON array of word entries, originally extracted from a PDF of Kamus Dewan. Each entry looks roughly like:
{
"word": "abadi",
"origin": "Ar",
"rootWord": "abad",
"aliases": ["abadi-abadi"],
"definitions": [
{ "sense": 1, "text": "..." },
{ "sense": 2, "text": "..." }
]
}
Schema quirks this tool accounts for:
- Numbered homonym variants — words like
"a I"/"a II"or"aba I"/"aba II"disambiguate unrelated words that happen to be spelled the same.kamus lookupshows all variants together when you search the bare word (a,aba), and shows only the requested one if you include the suffix explicitly ("aba II"). rootWord— links a derived form back to its base word (e.g.mengabadikan→abadi).kamus rootuses this to reconstruct full derivation families.aliases— related/alternate forms, shown alongside a lookup result but not used for indexing.sense— some definitions are numbered (multiple senses), some aren't (single sense, just atextfield). Both are rendered appropriately.origin— present for loanwords (Ar= Arabic,Id= Indonesian, etc.), absent otherwise.
Place the full 52K-entry dataset at data/kamus.json (a small sample is
included there for testing — replace it with the full file).
Installation
git clone <this repo>
cd kamus-cli
pip install -e .
This installs the kamus command globally (within your active Python
environment) via the project.scripts entry point in pyproject.toml.
Usage
kamus lookup <word>
Exact lookup. Shows origin, root word, aliases, and all definitions.
Numbered homonym variants are shown together if you omit the suffix.
Falls back to fuzzy (rapidfuzz) suggestions if there's no exact match.
kamus lookup abadi
kamus lookup aba # shows both "aba I" and "aba II"
kamus lookup "aba II" # shows only that one variant
kamus lookup abadii # no match -> "did you mean: abadi, abad, ..."
kamus random
Word of the day — a random entry with its full definition.
kamus random
kamus search <term>
Substring match across all words. Returns a word list only (definitions are omitted, since this can match many entries).
kamus search abad
kamus root <word>
Shows a word's root word (if any) and every other word in the dataset sharing that root — the full derivation family.
kamus root mengabadikan
# Root word: abadi
# Derivation family (3 other form(s)):
# - terabadi
# - keabadian
# - pengabadian
kamus root abadi # works from the root itself too
kamus export --format <csv|json|sqlite> --output <path>
Exports the full dataset.
json: the raw nested dataset, unflattened, written as-is.csv/sqlite: one row per definition (sense), not per word, sincedefinitionsis a nested array. Columns:word, origin, root_word, aliases, sense, definition_text. A word with 2 senses produces 2 rows sharing the same word/origin/etc. Seesrc/kamus/export.pyfor the full rationale.
kamus export --format csv --output kamus.csv
kamus export --format sqlite --output kamus.sqlite
kamus export --format json --output kamus_export.json
--json on every command
Every command accepts --json to print raw JSON instead of formatted
output, for scripting/piping:
kamus lookup abadi --json | jq '.[0].definitions'
kamus search abad --json
How the data is loaded
The full JSON file is loaded into memory once per process and indexed
(by exact word, by base word for homonym grouping, by root word for
derivation families) at startup. At ~52K entries this takes a fraction
of a second and keeps the implementation simple — see the docstring at
the top of src/kamus/data.py for the full reasoning, including when a
heavier on-disk index would actually be worth it.
Tests
pip install -e ".[test]"
pytest
Tests run against a small fixture (tests/fixtures/sample.json) drawn
from the real dataset's first ~14 entries, covering exact lookup,
homonym-variant handling, fuzzy-match fallback, root-word derivation
families, and export correctness (csv/json/sqlite).
Project structure
kamus-cli/
├── pyproject.toml
├── README.md
├── data/
│ └── kamus.json # full dataset goes here
├── src/kamus/
│ ├── __init__.py
│ ├── data.py # loading + indexing
│ ├── export.py # csv/json/sqlite export
│ └── cli.py # click commands
└── tests/
├── fixtures/sample.json
├── test_lookup.py
├── test_root.py
└── test_export.py
Metadata
Release files for kamus-cli 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| kamus_cli-0.1.1.tar.gz | 2.9 MB | Without provenance | Details for kamus_cli-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| kamus_cli-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for kamus_cli-0.1.1-py3-none-any.whl |
Total release size: 5.9 MB
Release files / kamus_cli-0.1.1.tar.gz
| Download URL | kamus_cli-0.1.1.tar.gz |
|---|---|
| Size | 2.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6439bf7cfd2e72e09479b2afc07183c1dffe755094853a6943de5b439293182
|
|
BLAKE2b-256 checksum How to use checksums |
94646a4e2460d5b444a40e0ab3931ee45aa3b3bd0e81180da8f05a98547f0619
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / kamus_cli-0.1.1-py3-none-any.whl
| Download URL | kamus_cli-0.1.1-py3-none-any.whl |
|---|---|
| Size | 3.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
51fb96c11023218d3c81e54732b2d1afd14c7809556e44b18bad7d436694fe83
|
|
BLAKE2b-256 checksum How to use checksums |
3ee7ef8fe1a4cb91e466dae0abc68209c22dc1d19441d2e493535ed2ffb25093
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for kamus-cli 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.