RapidFuzz
Fast fuzzy string matching and edit-distance metrics for Python, backed by a C++ core with an automatic pure-Python fallback.
Repository Health
Technical Analysis
RapidFuzz is a Python library for fuzzy string matching, edit-distance calculation, and string similarity scoring. It grew out of FuzzyWuzzy but rewrote the core in C++ for speed, fixed several bugs in FuzzyWuzzy’s partial-ratio implementation, and kept the license permissively MIT rather than GPL. It exposes both simple scorers (ratio, partial_ratio, token_sort_ratio, token_set_ratio, WRatio) through the fuzz module and a full set of named edit-distance metrics (Levenshtein, Indel, Jaro, JaroWinkler, Hamming, OSA, LCSseq, DamerauLevenshtein) through the distance subpackage, each with distance, normalized_distance, similarity, and normalized_similarity variants.
The process module builds on these scorers to compare one query against many candidate strings efficiently, offering extract, extractOne, extract_iter, and a cdist function for computing full pairwise similarity matrices — the batch path RapidFuzz recommends over calling scorers directly in a loop. Every metric ships with two implementations: a SIMD-accelerated C++ extension and a pure-Python fallback that RapidFuzz keeps behaviorally identical and separately tested, so the library still installs and runs correctly on platforms without a prebuilt wheel or C++ toolchain.
What You Get
- A
fuzzmodule withratio,partial_ratio,token_sort_ratio,token_set_ratio, andWRatio/QRatiocomposite scorers, drop-in compatible with FuzzyWuzzy’s API surface - A
distancesubpackage exposing named edit-distance metrics (Levenshtein, Indel, Hamming, Jaro, JaroWinkler, OSA, LCSseq, DamerauLevenshtein, Postfix, Prefix), each with distance/similarity and normalized variants - A
processmodule (extract,extractOne,extract_iter,cdist) for matching a query against a list or dict of choices, including a vectorized pairwise-matrix API for bulk comparisons - A
utilsmodule withdefault_processfor case-folding and stripping non-alphanumeric characters before scoring - Optional
numpy-backed output forcdistso large-scale batch comparisons return arrays instead of Python lists
Common Use Cases
- Deduplicating or record-linking near-identical entries (names, addresses, product titles) across datasets that lack a shared key
- Fuzzy autocomplete and “did you mean” search suggestions matching user input against a known vocabulary
- Entity resolution and data-cleaning pipelines that need to score similarity between free-text fields at scale via
cdist - Drop-in replacement for FuzzyWuzzy in existing codebases that want a permissive MIT license and a faster C++ core
- Spell-checking and typo-tolerant matching against a fixed dictionary of valid strings
Under The Hood
Architecture
RapidFuzz is built around a dual-implementation architecture repeated per metric: a C++/Cython extension (fuzz_cpp.pyx, metrics_cpp.pyx, process_cpp_impl.pyx, with SIMD variants split into _avx2/_sse2 files and shared logic in cpp_common.hpp) and a parallel pure-Python implementation (fuzz_py.py, metrics_py.py, process_py.py, and per-metric *_py.py files under distance/). A _feature_detector.py/_initialize.py layer picks which backend to load at import time — based on whether the compiled extension built successfully or the RAPIDFUZZ_IMPLEMENTATION environment variable is set — and each public module (e.g. fuzz.py, distance/Levenshtein.py) is a thin re-export that delegates to whichever backend was selected, so callers never touch the split directly. The process module layers query-against-many-choices matching (extract, extractOne, cdist) on top of the same per-metric scorer functions rather than reimplementing comparison logic.
Tech Stack
The project targets Python 3.11+ and builds its native extension with a C++17 toolchain via scikit-build-core and CMake, with Cython 3.1–3.3 generating the C++ bindings from .pyx sources; cibuildwheel (with PyPy enabled) produces cross-platform wheels for CI releases, and an optional numpy extra lets cdist return arrays instead of plain lists. Static analysis runs through ruff (a broad rule set including bugbear, pylint, and NumPy-specific checks), mypy in strict mode against src, and black/pylint as secondary checks, with Sphinx generating the published documentation site.
Code Quality
The tests/ directory runs pytest against both a fuzz/process/utils suite and a dedicated distance/ suite, uses Hypothesis for property-based testing (test_hypothesis.py), and — notably — includes test_cpp_fallback.py and test_pure_python_fallback.py, which explicitly force each backend via the RAPIDFUZZ_IMPLEMENTATION environment variable to verify the two implementations stay behaviorally identical rather than trusting them to agree by construction. CI is split across dedicated branch-build, coverage, release-build, and submodule workflows, with Codecov tracking coverage and mypy --strict enforced on the Python-facing source tree.
What Makes It Unique
Where most fuzzy-matching libraries either stay pure Python (slow) or ship a single compiled extension with no fallback, RapidFuzz maintains and tests two independent implementations of every metric so it degrades gracefully to pure Python on platforms without a prebuilt wheel or working C++ toolchain, while still exposing SIMD-accelerated (AVX2/SSE2) code paths and a vectorized cdist batch API for the common case of comparing one query against a large candidate set. It also fixes several documented correctness bugs in FuzzyWuzzy’s partial_ratio implementation while remaining close enough to its API to serve as a near drop-in replacement.
Used by 11 apps in this directory
PostHog
Ab Testing Experimentation · Analytics · Developer Tools
The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.
Weblate
Developer Tools
Continuous localization platform that commits translations directly into your version control system with full translator attribution.