Skip to content

recipe: rapidfuzz 3.14.5#111

Open
ndonkoHenri wants to merge 3 commits into
mainfrom
rapidfuzz
Open

recipe: rapidfuzz 3.14.5#111
ndonkoHenri wants to merge 3 commits into
mainfrom
rapidfuzz

Conversation

@ndonkoHenri

Copy link
Copy Markdown

Adds a mobile-forge recipe for RapidFuzz 3.14.5 — fast fuzzy string matching (Levenshtein and other string metrics) with a C++ backend; an MIT-licensed, orders-of-magnitude-faster drop-in for fuzzywuzzy. Requested in flet-dev/flet#6717.

Why it's straightforward

RapidFuzz is a self-contained scikit-build-core + CMake + Cython C++ package — the duckdb/pyzmq archetype. Its only native "dependencies" are the header-only rapidfuzz-cpp and Taskflow submodules, both bundled in the PyPI sdist, so there's no external native library to build and no companion recipe (the base install has zero mandatory runtime deps). Built with zero patches.

Recipe shape / notable decisions

  • RAPIDFUZZ_BUILD_EXTENSION=1 in script_env — without it, scikit-build-core silently falls back to a pure-Python wheel (no .so); this forces the compiled extension and fails loudly if the cross-build breaks.
  • x86 SSE2/AVX2 are separate CMake targets gated on RAPIDFUZZ_ARCH_X86/X64 (a try_compile on __x86_64__/__i386__), so ARM slices build only the scalar path — no x86 intrinsics ever reach the ARM compiler. On-device you get the scalar C++ implementation, still far faster than pure Python.
  • flet-libcpp-shared is an Android-only host dep (libc++_shared for the C++ .so); iOS links the system libc++.
  • Development.Module FindPython is satisfied by the standard CROSS_VENV_PYTHON / -DPython_* injection.

Validation

  • Full CI matrix green: Python 3.12 / 3.13 / 3.14 × android + iOS (all 6 build legs). Android covers all ABIs including armeabi-v7a (the libatomic path resolves via NDK-provided libatomic — no exclusion needed).
  • On-device tests pass on the 3.12 legs (Android emulator + iOS simulator): import, the compiled rapidfuzz.fuzz_cpp canary, Levenshtein.distance, and a Taskflow-backed process.extractOne.
  • Local iphonesimulator:arm64 build verified (all five compiled modules; MH_BUNDLE → MH_DYLIB fix auto-applied).

Consumer notes (usage & recommendations)

RapidFuzz is fast fuzzy string matching for Flet apps — search, autocomplete, dedupe, and fuzzy lookups, all computed on-device by its C++ core. It's a drop-in, much faster replacement for fuzzywuzzy, and MIT-licensed.

Install

Once published, just add it to your app's pyproject.toml:

dependencies = [
  "flet",
  "rapidfuzz",
]

No extra dependencies — the base install is self-contained. (numpy is optional, pulled only via the rapidfuzz[all] extra for array-batch ops; you don't need it for normal use.) Works on all Android ABIs (arm64-v8a, x86_64, armeabi-v7a) and iOS.

Minimal example — a live fuzzy search that shows ranked matches with scores:

import flet as ft
from rapidfuzz import process, fuzz

FRUITS = ["apple", "banana", "orange", "pineapple", "grapefruit",
          "strawberry", "blueberry", "watermelon", "mango", "peach"]

def main(page: ft.Page):
    page.title = "RapidFuzz demo"
    results = ft.ListView(expand=True, spacing=6)

    def search(e):
        query = e.control.value.strip()
        results.controls.clear()
        if query:
            # top-5 fuzzy matches, scored by the C++ backend
            for name, score, _ in process.extract(query, FRUITS,
                                                   scorer=fuzz.WRatio, limit=5):
                results.controls.append(ft.Text(f"{name}{score:.0f}%", size=18))
        page.update()

    page.add(
        ft.TextField(label="Type a fuzzy fruit name", autofocus=True, on_change=search),
        ft.Divider(),
        results,
    )

ft.run(main)

Type appelapple ranks first; bannabanana. The scoring runs entirely offline in the compiled C++ extension.

What you get

  • rapidfuzz.fuzz — similarity scorers (ratio, partial_ratio, token_sort_ratio, WRatio, …).
  • rapidfuzz.processextract / extractOne / cdist for matching a query against many choices.
  • rapidfuzz.distance — edit-distance metrics (Levenshtein, JaroWinkler, Hamming, …). The former jarowinkler and rapidfuzz_capi packages are merged in, so you don't need them — and you don't need python-Levenshtein for distances.

Threading — interactive search over a modest list (as above) is fine on the UI thread. For heavy batch work — deduping thousands of records, or a large process.cdist — run it in page.run_thread(...) so the UI stays responsive.

Performance note — on mobile you get the scalar C++ path (the x86 SSE2/AVX2 kernels are x86-only and aren't part of the ARM build). That's still dramatically faster than any pure-Python fuzzy matcher — the compiled extension is active, not the fallback. Prefer process.extract/cdist over Python loops for batch matching, and pick the lightest scorer that fits (ratio is cheaper than WRatio).

Offline — fully offline; no network, no data files, no storage wiring needed.

Fast fuzzy string matching (flet-dev/flet#6717). Self-contained
scikit-build-core + CMake + Cython C++ package, duckdb/pyzmq archetype,
zero patches. The vendored rapidfuzz-cpp and Taskflow deps are header-only
and bundled in the sdist, so there is no external native library to build.

Notes:
- RAPIDFUZZ_BUILD_EXTENSION=1 forces the compiled C++ extension; without it
  scikit-build-core silently falls back to a pure-Python wheel (no .so).
- Its x86 SSE2/AVX2 SIMD variants are separate CMake targets gated on
  $RAPIDFUZZ_ARCH_X86/X64 (try_compile on __x86_64__/__i386__), so ARM slices
  build only the scalar path -- no x86 intrinsics reach the ARM compiler.
- flet-libcpp-shared is an Android-only host dep (libc++_shared) for the
  C++ .so; iOS links the system libc++.

Locally verified: ios_13_0_arm64_iphonesimulator builds clean (all five
compiled modules incl. process_cpp_impl), MH_BUNDLE->MH_DYLIB fix applied,
"C++ Extension built successfully".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant