Skip to main content

pinyinIME

Know how to solve every problem that has been solved. -- Feynman

A simple Pinyin Input Method Engine, inspired by Rime.

Pure Python implementation, with no dependencies on any third-party libraries.

Under 500 lines of code!

It is the Chinese input method I currently use in my daily life.

Features

  • Full pinyin & abbreviation — nihao → 你好;nh → 你好(声母缩写)
  • Manual syllable separation(configurable) — xi'an → 西安; ke'neng → 可能
  • Emoji input — type Chinese keywords to get emoji candidates
  • Traditional Chinese — optional simplified → traditional conversion
  • Python API — embed the engine directly in your own Python app
  • Custom phrases
  • HTTP server — local HTTP daemon for integration with native input method frameworks (e.g. macOS IMKit / Swift)
  • Interactive terminal UI — optional TUI for trying the IME in your terminal (connects to the HTTP server)
    • User learning — records your word choices and promotes them in future lookups

Installation

pip install pinyinIME

Or with uv:

uv tool install pinyinIME

To enable traditional Chinese output, install with the optional dependency:

pip install "pinyinIME[traditional]"

Python API

from pinyinIME.engine import PinyinEngine

engine = PinyinEngine()

# Get candidate words (page=0, page_size=9)
engine.query("nihao", 0, 9)
# {
#   "syllables": ["ni", "hao"],
#   "candidates": [{"word": "你好", "syllables": ["ni", "hao"]}, ...],
#   "max_page": 20
# }

# Get candidates with full pinyin and frequency score
engine.lookup("nh")
# [('你好', 'ni hao', 135314), ('那好', 'na hao', 812), ...]

# FMM syllable segmentation
engine.segment("nihao")      # ['ni', 'hao']

# Record a user selection
engine.commit("你好", ["ni", "hao"])

CLI Usage

# Look up candidates for a pinyin string
pinyinIME lookup nihao
pinyinIME lookup nh           # abbreviation: 声母缩写
pinyinIME lookup "xi'an"      # manual syllable split → 西安

# Open debug playground in browser (requires server running)
uv run --with bottle pinyinIME serve   # start HTTP server first
pinyinIME playground                   # then open playground in browser

# Enable debug logging
pinyinIME --verbose lookup nihao

# Interactive terminal UI (requires bottle + rich; start server first)
uv run --with bottle pinyinIME serve                              # start HTTP server (default 127.0.0.1:12358)

uv run  pinyinIME playground     # open browser playground (recommended) ✨
uv run --with rich pinyinIME interactive     # or use terminal interactive UI

Development

git clone https://github.com/wwj718/pinyinIME.git
cd pinyinIME

# Install in editable mode (changes take effect immediately)
uv tool install --editable .

# Run tests
uv run pytest

# Full QA (format, lint, type check, test)
just qa

Architecture Overview

PinyinEngine
├── index/
│   ├── builder.py   IndexBuilder → (Prism, Table)
│   ├── prism.py     Spelling → [(syllable_id, SpellingType)]
│   └── table.py     Trie: syllable_id[] → DictEntry[] (sorted by score)
├── pipeline/
│   ├── types.py        SpellingType enum, SPELLING_PENALTY constants
│   ├── segmentor.py    FmmStrategy (forward maximum matching, O(n×6))
│   ├── translator.py   Querier: DFS over segments, Prism+Table lookup, timeout protection
│   └── filter.py       Filter Protocol; TraditionalFilter (simp→trad)
├── tools/
│   ├── cli.py          Typer CLI: lookup / interactive / clear-cache commands
│   ├── server.py       HTTP daemon (bottle); exposes query/commit/segment API
│   ├── interactive.py  Interactive terminal UI (HTTP client mode)
│   └── user_history.py UserHistory management CLI
└── engine.py           PinyinEngine: init, lookup(), candidates(), select(), commit()

Scoring

Candidates are ranked by an adjusted score:

adjusted_score = round((log(max(raw_score, 1)) + spelling_penalty) × 1_000_000)

Weight multipliers before the log:

Source Multiplier
User history 10,000,000
Custom phrases 1,000,0 * (1-100)
Emoji 1,000
Essay (Rime) base 1

Spelling penalties: NORMAL → 0.0, ABBREVIATION → log(0.1) ≈ −2.303

Author

pinyinIME was created in 2026 by Wenjie Wu.

Built with the cookiecutter-pypackage project template.

Metadata

Release files for pinyinIME 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pinyinIME 0.2.0
File Interpreter ABI Platform Actions
pinyinime-0.2.0-py3-none-any.whl Python 3 none any Details for pinyinime-0.2.0-py3-none-any.whl

Release files / pinyinime-0.2.0-py3-none-any.whl

Download URL pinyinime-0.2.0-py3-none-any.whl
Size 4.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e3fc98063bf110c6d405fa7fb1f430fe3ef333913a8ef8ed5be90dd801a923b2
BLAKE2b-256 checksum
How to use checksums
bc0d9ccdfafa11e5e635da2eb0ca9fe13ac675aac2e35d8fffd38383f517f034
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.13

Security for pinyinIME 0.2.0

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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

1 release file No provenance

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