Skip to main content

TurboText

TurboText

Lightning-fast, boundary-aware keyword matching for Python
Exact · Fuzzy · Multi-word · Unicode · Pluggable conflict resolution

PyPI Python License CI Typed Cython


TurboText finds keywords in text the way a human editor would — enforcing real word boundaries, tolerating typos, handling multi-word phrases, and letting you declare which match wins when keywords overlap, including an optimal (not just greedy) weighted resolver that no other keyword library provides.


Table of Contents


Why TurboText?

re FlashText RapidFuzz TurboText
Exact keyword extraction
Fuzzy / typo-tolerant
Word boundary enforcement
Extracts spans from running text
Multi-word phrases (native) ⚠️
O(text) scaling with vocab
Per-keyword metadata
Conflict resolution policies
Optimal weighted resolution

Features

  • Exact matching — trie-based O(n) scan, constant in vocabulary size
  • Fuzzy matching — Levenshtein distance up to k via bounded-edit frontier search
  • Word boundary enforcement — Unicode-correct; matches cat but not cats, scat, or concatenate
  • Multi-word keywords"new york", "product manager" work out of the box
  • Bulk loading — accepts list, dict[str, str], or dict[str, list[str]]
  • Five conflict policiesALL_OVERLAPS, LEFTMOST_LONGEST, LEFTMOST_FIRST, HIGHEST_PRIORITY, OPTIMAL_WEIGHTED
  • Optimal resolution — O(n log n) weighted interval scheduling DP — picks the globally best non-overlapping set
  • Rich match objects — canonical form, offsets, edit distance, category, priority, custom metadata
  • Cython fast-path — compiled extension ships with every wheel; packed transition-table automaton, 1.5× faster than FlashText on 1 M-word corpora

Installation

pip install turbotext

The Cython extension is built automatically when installing from PyPI (wheels are pre-compiled for CPython 3.10–3.13 on Linux, macOS, and Windows). No extra steps needed.

TurboText falls back to pure Python automatically if the compiled extension is unavailable (e.g. unsupported platform or source install without a C compiler).

Install with uv (development)
git clone https://github.com/nishankmahore/TurboText
cd TurboText
uv sync --group dev
python setup.py build_ext --inplace

Quick Start

from turbotext import KeywordStore, MatchPolicy, FuzzyConfig

store = KeywordStore(
    policy=MatchPolicy.LEFTMOST_LONGEST,
    fuzzy=FuzzyConfig(max_edit_distance=1),
)

store.add_keywords({
    "aspirin":   ["aspirin", "asprin", "aspirin tablet"],
    "ibuprofen": ["ibuprofen", "ibuprofen tablet"],
})

text = "Patient takes asprin and ibuprofen tablet daily"

for m in store.extract(text):
    print(f"{m.canonical:12}  ed={m.edit_distance}  [{m.start}:{m.end}]  '{m.text}'")
# aspirin       ed=1  [14:20]  'asprin'
# ibuprofen     ed=0  [25:42]  'ibuprofen tablet'

print(store.replace(text))
# Patient takes aspirin and ibuprofen daily

Adding Keywords

Single keyword

store = KeywordStore()

# minimal — surface form becomes the canonical
store.add_keyword("aspirin")

# with canonical form
store.add_keyword("aspirin", canonical="Aspirin")

# with full metadata
kid = store.add_keyword(
    "aspirin",
    canonical="Aspirin",
    category="DRUG",
    priority=10.0,
    rxnorm_code="1191",   # any extra kwargs become metadata
    source="rxnorm",
)
print(kid)  # "3f4a2b1c-..."  UUID — useful for tracking

From a list

store.add_keywords(["java", "python", "rust"])
# surface form = canonical for each entry

From a {surface: canonical} dict

store.add_keywords({
    "py":   "Python",
    "js":   "JavaScript",
    "k8s":  "Kubernetes",
})

From a {canonical: [surfaces]} dict (most common bulk shape)

keyword_dict = {
    "java":               ["java", "java_2e", "java programing"],
    "product management": ["PM", "product manager", "prod mgmt"],
    "machine learning":   ["ML", "machine learning", "deep learning"],
}
store.add_keywords(keyword_dict)

Mixed dict

String values follow {surface: canonical}; list values follow {canonical: [surfaces]}.

store.add_keywords({
    "java": ["java_2e", "java programing"],  # canonical → [surfaces]
    "py":   "Python",                         # surface   → canonical
})

Shared category and priority

store.add_keywords(
    {
        "aspirin":   ["aspirin", "asprin"],
        "ibuprofen": ["ibuprofen", "advil"],
    },
    category="DRUG",
    priority=5.0,
)

Extracting Matches

matches = store.extract("take aspirin and ibuprofen daily")

for m in matches:
    print(m.text)           # surface text found in the input
    print(m.canonical)      # normalised keyword name
    print(m.start, m.end)   # character offsets — text[m.start:m.end]
    print(m.edit_distance)  # 0 = exact, 1 = one typo, etc.
    print(m.category)       # "DRUG"
    print(m.priority)       # 10.0
    print(m.keyword_id)     # UUID string
    print(m.metadata)       # {"rxnorm_code": "1191", ...}

Match uses __slots__ for fast bulk creation — all fields are fixed and the object is lightweight.


Replacing Keywords

store = KeywordStore()
store.add_keywords({
    "aspirin":       "Aspirin",
    "tylenol":       "Acetaminophen",   # alias → same canonical
    "ibuprofen":     "Ibuprofen",
})

print(store.replace("take aspirin or tylenol twice daily"))
# take Aspirin or Acetaminophen twice daily

Fuzzy Matching

from turbotext import FuzzyConfig

store = KeywordStore(fuzzy=FuzzyConfig(max_edit_distance=1))
store.add_keyword("aspirin")

store.extract("take asprin")    # substitution  i → r  ✅
store.extract("take aspirn")    # deletion      missing i  ✅
store.extract("take aspirrin")  # insertion     extra r  ✅

Boundary enforcement still applies

store.extract("I see cbt")   # ✅ whole word
store.extract("I see xcbt")  # ❌ left boundary fails
store.extract("I see cbts")  # ❌ right boundary fails

Choosing max_edit_distance

Value Use case
0 Exact matching only (default) — uses Cython fast-path when available
1 Single-character typos — medical terms, product names — uses Cython fast-path when available
2 Two-character errors — longer technical terms — uses Cython fast-path when available

Higher values increase recall but also false positives. Start with 1 and tune.


Conflict Resolution Policies

When keywords overlap, the policy decides which match to keep.

ALL_OVERLAPS — return everything, you decide
store = KeywordStore(policy=MatchPolicy.ALL_OVERLAPS)
store.add_keywords(["new", "new york", "york"])

store.extract("new york")
# → ["new", "new york", "york"]
LEFTMOST_LONGEST (default) — FlashText-compatible greedy
store = KeywordStore(policy=MatchPolicy.LEFTMOST_LONGEST)
store.add_keywords(["new", "new york"])

store.extract("new york")
# → ["new york"]   longest match wins
LEFTMOST_FIRST — earliest start wins
store = KeywordStore(policy=MatchPolicy.LEFTMOST_FIRST)
store.add_keywords(["new", "new york"])

store.extract("new york")
# → ["new"]   first token wins
HIGHEST_PRIORITY — priority-based greedy
store = KeywordStore(policy=MatchPolicy.HIGHEST_PRIORITY)
store.add_keyword("new york", canonical="New York", priority=2.0)
store.add_keyword("york",     canonical="York",     priority=5.0)
store.add_keyword("new",      canonical="New",      priority=1.0)

store.extract("new york")
# → ["New", "York"]   priority 5 beats priority 2; "new" doesn't overlap "york"
OPTIMAL_WEIGHTED — globally optimal, not greedy
store = KeywordStore(policy=MatchPolicy.OPTIMAL_WEIGHTED)
store.add_keyword("ab cd", canonical="LONG",   priority=5.0)
store.add_keyword("ab",    canonical="SHORT1", priority=3.0)
store.add_keyword("cd",    canonical="SHORT2", priority=3.0)

store.extract("ab cd")
# Greedy picks "LONG" (5).  Optimal picks "SHORT1"+"SHORT2" (3+3=6).
# → ["SHORT1", "SHORT2"]

Per-Keyword Metadata

store.add_keyword(
    "aspirin",
    canonical="Aspirin",
    category="DRUG",
    priority=10.0,
    rxnorm_code="1191",
    source="rxnorm",
    approved=True,
)

m = store.extract("take aspirin")[0]
print(m.canonical)               # "Aspirin"
print(m.category)                # "DRUG"
print(m.priority)                # 10.0
print(m.metadata["rxnorm_code"]) # "1191"

Match.metadata is a shallow copy — mutating it does not affect the stored keyword.


Word Boundary Rules

TurboText uses Unicode word boundaries — word characters are [a-zA-Z0-9_] and their Unicode equivalents.

store.add_keyword("cat")

# ✅ Accepted
store.extract("cat")          # text edge
store.extract("the cat sat")  # spaces
store.extract("(cat)")        # punctuation
store.extract("cat, sat")     # comma

# ❌ Rejected
store.extract("cats")         # right boundary fails
store.extract("scat")         # left boundary fails
store.extract("cat2")         # digit is a word char
store.extract("concatenate")  # substring

Performance

Apple M-series · best-of-3 runs · Cython extension enabled

1 M-word throughput (1,000 keywords, 7.8 MB corpus)

TurboText's Aho-Corasick engine with inline lowercasing and zero-copy resolve beats FlashText on large documents.

1M throughput

Library Time (s) Matches vs FlashText
TurboText (k=0) 0.54 ~500,000 1.5× faster
FlashText 0.79 ~500,000 baseline

Exact matching vs regex — vocabulary scaling (k=0)

TurboText is O(text) — scan time is flat as vocabulary grows. re alternation degrades linearly with term count because every disjunct is tried at every position.

The k=0 engine is a packed transition table: the Aho-Corasick automaton is flattened into one contiguous int32 array (state*128+char → next_state) instead of a graph of individually heap-allocated trie nodes. Transitions become a single branchless array index — no null-check, no pointer chase through separate node/list/array allocations — so the win grows with automaton size as more of the old pointer graph would have spilled out of cache.

k=0 vs regex

Library 100 terms 1,000 terms 5,000 terms 20,000 terms Complexity
TurboText 1.2 ms 1.3 ms 1.4 ms 1.6 ms O(text)
re 4.8 ms 40.1 ms 213.3 ms 846.1 ms O(text × vocab)

Exact matching vs the Aho-Corasick family (k=0)

Separated from the regex comparison above because it's a different question: every library here is already O(text), so the story isn't complexity class, it's implementation constants — Python-object overhead, boundary handling, and (for the C extension) FFI/allocation cost. pyahocorasick's C core wins on raw scan speed but hands back plain substring spans with no boundary awareness or multi-word phrase support — it's a general-purpose multi-pattern search primitive, not a keyword-extraction library.

TurboText (spans) is extract_spans(): the same FlatAC engine as extract(), but returning bare (start, end, keyword_id) tuples instead of building a Match object per hit (no text-slice, no attribute assignment, no metadata dict). Keyword refs are int-indexed internally (an array lookup) rather than hashed by a 36-char uuid string, so this is close to pyahocorasick's raw-scan speed while still being boundary-aware. extract() pays the difference for Match objects — canonical form, category, priority, metadata — which pyahocorasick doesn't have a concept of at all.

k=0 vs Aho-Corasick family

Library 100 terms 1,000 terms 5,000 terms 20,000 terms Boundary-aware
TurboText 1.2 ms 1.3 ms 1.3 ms 1.5 ms
TurboText (spans) 0.5 ms 0.5 ms 0.6 ms 0.7 ms
FlashText 2.9 ms 3.0 ms 3.1 ms 3.2 ms
flashtext2 1.1 ms 1.1 ms 1.1 ms 1.1 ms
pyahocorasick 0.4 ms 0.6 ms 0.6 ms 0.7 ms

Fuzzy matching vs FuzzyWuzzy — vocabulary scaling (k=1)

TurboText's fuzzy path (bounded-edit frontier search) is a Cython fast path, same as exact matching: a single-pass trie scan regardless of vocabulary size. FuzzyWuzzy tokenises the text and scores every token against every keyword with a pure-Python-Levenshtein-backed ratio — O(tokens × vocab), and it shows: 5,000 keywords take over 11 seconds.

k=1 vs FuzzyWuzzy

Library 100 terms 500 terms 1,000 terms 2,000 terms 5,000 terms
TurboText 18 ms 32 ms 48 ms 56 ms 70 ms
FuzzyWuzzy 222 ms 1,098 ms 2,231 ms 4,398 ms 11,394 ms

Fuzzy matching vs RapidFuzz, python-Levenshtein, jellyfish (k=1)

A separate chart because these three don't share FuzzyWuzzy's story: RapidFuzz has a genuinely C-accelerated batch primitive (process.extractOne), while python-Levenshtein and jellyfish only expose a single-pair distance function — no batch "find the best match in this list" API — so a token × keyword nested loop calling their distance function is the realistic way to use them here, not an artificial handicap. That nested loop puts jellyfish in the same ballpark as FuzzyWuzzy above (11.1s vs 11.4s at 5,000 terms) despite jellyfish's distance function itself being fast in isolation.

k=1 vs RapidFuzz/python-Levenshtein/jellyfish

Library 100 terms 500 terms 1,000 terms 2,000 terms 5,000 terms Boundary-aware Extracts spans
TurboText 18 ms 32 ms 44 ms 55 ms 69 ms
RapidFuzz 13 ms 62 ms 121 ms 244 ms 608 ms
python-Levenshtein 58 ms 290 ms 576 ms 1,157 ms 2,879 ms
jellyfish 224 ms 1,130 ms 2,220 ms 4,471 ms 11,127 ms

TurboText overtakes RapidFuzz at ~500 keywords and is 8.8× faster at 5,000 terms. Unlike RapidFuzz (a string scorer used with process.extractOne per token), TurboText returns character offsets, enforces word boundaries, and handles multi-word phrases natively — and unlike python-Levenshtein/jellyfish, it never needs an O(tokens × vocab) nested loop in the first place.


API Reference

KeywordStore(policy, fuzzy)
store = KeywordStore(
    policy=MatchPolicy.LEFTMOST_LONGEST,    # default
    fuzzy=FuzzyConfig(max_edit_distance=0), # default — exact only
)
Parameter Type Default Description
policy MatchPolicy LEFTMOST_LONGEST Conflict-resolution strategy
fuzzy FuzzyConfig | None None Fuzzy config; None = exact only
add_keyword(surface_form, *, canonical, category, priority, **metadata) → str
kid = store.add_keyword(
    "aspirin",
    canonical="Aspirin",
    category="DRUG",
    priority=10.0,
    rxnorm_code="1191",
)
Parameter Type Default Description
surface_form str required Text to search for
canonical str surface_form Normalised name returned on match
category str | None None Grouping label
priority float 1.0 Weight for priority-based policies
**metadata Any Arbitrary extra fields

Returns the keyword's UUID string.

add_keywords(keywords, *, category, priority) → list[str]
Shape Example
list[str] ["java", "python"]
dict[str, str] {"py": "Python"} — surface → canonical
dict[str, list[str]] {"Python": ["py", "python3"]} — canonical → surfaces

category and priority apply to every keyword in the call.

extract(text) → list[Match]

Returns resolved matches in span order.

matches = store.extract("Patient takes aspirin daily")
extract_spans(text) → list[tuple[int, int, str]]

Fast path: (start, end, keyword_id) tuples, no Match object built. For exact + LEFTMOST_LONGEST (the default), this skips text-slicing, attribute assignment, and metadata handling per match — see the k=0 benchmarks above. Other configurations still return correct results via extract() with the Match objects stripped, just without the speed benefit.

for start, end, keyword_id in store.extract_spans("Patient takes aspirin daily"):
    ...
replace(text) → str

Replaces every matched span with its canonical form.

result = store.replace("take aspirin or tylenol")
Match fields

Match uses __slots__ — all fields are set at construction and the object is lightweight.

Field Type Description
text str Matched surface text as it appears in the input
canonical str Normalised form from add_keyword
start int Start character offset
end int End character offset (exclusive)
edit_distance int Levenshtein distance (0 = exact)
category str | None User-supplied category
priority float User-supplied priority
keyword_id str UUID from add_keyword
metadata dict Copy of extra kwargs
FuzzyConfig and MatchPolicy
FuzzyConfig(max_edit_distance=1)  # int, default 0
MatchPolicy Description
ALL_OVERLAPS Return every match
LEFTMOST_LONGEST Greedy — leftmost, then longest
LEFTMOST_FIRST Greedy — leftmost, then insertion order
HIGHEST_PRIORITY Greedy — highest priority wins cluster
OPTIMAL_WEIGHTED Exact — maximise total priority globally

Development

uv sync --group dev                        # install dependencies
python setup.py build_ext --inplace        # build Cython extension
uv run pytest                              # run tests
uv run ruff check src tests                # lint
uv run mypy src/turbotext                  # type-check
uv run pytest benches/ --benchmark-only    # throughput benchmarks
uv run python benches/bench_1m_words.py    # 1 M-word TurboText vs FlashText
uv run python benches/scaling_benchmark.py # regenerate scaling charts
Project layout
src/turbotext/
    __init__.py       public API exports
    trie.py           TrieNode + TrieBuilder
    frontier.py       bounded-edit frontier search (pure Python fallback)
    _fast.pyx         Cython hot-path for exact (k=0) and fuzzy (k>0) search
    _fast.pyi         type stub for the Cython extension
    resolve.py        conflict-resolution policies
    store.py          KeywordStore public class
reference/
    reference_matcher.py    brute-force oracle for differential testing
tests/
    test_m0_smoke.py                   API surface + add_keywords shapes
    test_m1_exact.py                   exact matching + boundary rules
    test_m2_metadata_priorities.py     metadata, HIGHEST_PRIORITY, OPTIMAL_WEIGHTED
    test_m3_fuzzy.py                   fuzzy matching + hypothesis property tests
benches/
    bench_m3.py             pytest-benchmark: k=0 vs k=1 throughput
    bench_comparison.py     pytest-benchmark: TurboText vs FlashText vs re vs RapidFuzz
    bench_1m_words.py       1 M-word throughput: TurboText vs FlashText
    scaling_benchmark.py    vocabulary-sweep scaling charts
assets/
    logo.png

Author

Nishank Mahore
nishankmahore@gmail.com · github.com/nishankmahore

If TurboText is useful to you, feel free to open an issue, suggest a feature, or contribute a pull request.


License

Released under the MIT License — see LICENSE for the full text.


Made with Python · Powered by Cython · Built for speed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turbotext-0.3.0.tar.gz (157.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

turbotext-0.3.0-cp313-cp313-win_amd64.whl (196.1 kB view details)

Uploaded CPython 3.13Windows x86-64

turbotext-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl (509.1 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

turbotext-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl (488.7 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

turbotext-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (490.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

turbotext-0.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (493.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

turbotext-0.3.0-cp313-cp313-macosx_11_0_arm64.whl (202.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

turbotext-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl (204.6 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

turbotext-0.3.0-cp312-cp312-win_amd64.whl (196.6 kB view details)

Uploaded CPython 3.12Windows x86-64

turbotext-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl (511.5 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

turbotext-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl (492.7 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

turbotext-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (496.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

turbotext-0.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (497.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

turbotext-0.3.0-cp312-cp312-macosx_11_0_arm64.whl (202.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

turbotext-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl (205.0 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

turbotext-0.3.0-cp311-cp311-win_amd64.whl (196.6 kB view details)

Uploaded CPython 3.11Windows x86-64

turbotext-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl (529.6 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

turbotext-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl (513.0 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ ARM64

turbotext-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (512.0 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

turbotext-0.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (511.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

turbotext-0.3.0-cp311-cp311-macosx_11_0_arm64.whl (203.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

turbotext-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl (204.0 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

turbotext-0.3.0-cp310-cp310-win_amd64.whl (196.6 kB view details)

Uploaded CPython 3.10Windows x86-64

turbotext-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl (502.4 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

turbotext-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl (486.5 kB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ ARM64

turbotext-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (483.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

turbotext-0.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (481.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

turbotext-0.3.0-cp310-cp310-macosx_11_0_arm64.whl (204.0 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

turbotext-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl (204.2 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

File details

Details for the file turbotext-0.3.0.tar.gz.

File metadata

  • Download URL: turbotext-0.3.0.tar.gz
  • Upload date:
  • Size: 157.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbotext-0.3.0.tar.gz
Algorithm Hash digest
SHA256 36cacb4d7bde5a91b6d2fd2856470f4ece132310437449c5224c5a5cc2462633
MD5 ae8772adddbc869d2e6642c4c620db92
BLAKE2b-256 75a78d75412f616216783fffaf48aa885ac3cbf69070ab7b173c0966bc5c7d35

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: turbotext-0.3.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 196.1 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 3028d442279bc598775c87307aa6613fb4f85ec82043a602327af0dbf0a06198
MD5 f29143496fc373cd87c18b496ee5b838
BLAKE2b-256 5d941f3834ef69126ec02a8c29f2b8cd3cd87bfa3a94713c5c81cd17d69976e6

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d53b49de24ee2b05fbc7645321b3f2ec0ea90f10ec8ae335a3b57442f1e75d3a
MD5 d36b79cd012383167afdfaffde861f50
BLAKE2b-256 113d9466c71167105c1c2d6e684a45329f94da6e2dd73311c26a368c03c17e05

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0d8f411bcea1302d6b4f3c4f71b7d5ef1002130a3db705b4a0c13dce7283611b
MD5 326d720e9e27c221ef00590fbe78fac1
BLAKE2b-256 d771ee6a9ce026a04a6b227c963fb0e2d2376932290846147084f18ac8be878d

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3f1a3699d2857fdab049d55b8e7aa8a63781848f673764a3a1b6f9aaa59cf038
MD5 07429358bee64e481d650d9fff19d5d2
BLAKE2b-256 2e3ca558faed7cd06505f39ad9110ab78d518d6476475f6f039d9327c8aa24a0

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d759f30590c133e7456264536a5e62961884030c6e539cc96927b8c6406914ad
MD5 e8f3c594d062000b24cab40a0907f32d
BLAKE2b-256 f4cc3b80a1835ec3fb911bed1589d70669e37f4d0cbcabf1c72127e1bab4d3f7

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 59641b41f238b821386b2376a233484ac6745bc669b5c0f0741d4e9ef55405b1
MD5 c1718231ecfb6005a87b352eface2fbe
BLAKE2b-256 ec27e1f91f44ab62ee7136485ecc60fba214fd5ae5cfebcdc42d8aee7a102a92

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 ed2a77996554969d99d5f616a347a42659cc89abffae929861e6d31b993398c4
MD5 6d499754ab3d7cdbf9ee8a73dacd2e92
BLAKE2b-256 ce1c0171aca0bb0593a0ed1af8aa905630d9c286373b5dce0ff840fa13712963

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: turbotext-0.3.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 196.6 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 bb3e8bf8c24a021732740cbaf3f5b32e8c4c88aabe60515c43d18f32dd572dcb
MD5 184800c005b6d1a5bb98dbe14e39d844
BLAKE2b-256 069280f4e149a78c9e63108723c7fbbf1413226034a299e6a3e99d6f1cc04ed4

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8aac5565305f7b27a7803f05c7f02f94bd2dd59cd3fbb4d7eaf44906264f0318
MD5 e155d3797e35e2391e8e060085de92bf
BLAKE2b-256 90e624413141be28f69ed676a05b3a44dc3b59f7dcd25f0b2e4c15290a78d664

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 5ce3903ce5ffe64bff342b2fbb5f8b87eecee97e6b6d57bc4448de7af26b7e16
MD5 b0ca5f1ea7ccdac8228cb306c60ce343
BLAKE2b-256 9f43fa9921b68dc33e1d955872f5d13088d2d8532db55af39c07e957a9949e98

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8f1b980cce661cf30eecad5da628c0dc5a0d6b4f62076d0fc36a202a1349ebdb
MD5 b3662a9a56da01a794ba4b6a196ae0fe
BLAKE2b-256 1db44aab7b1a44ea877fceb34140a61f8b380905279fa2e6075cead372fd4350

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b7512d0e7b061428e40f0731b6dab287456857a04da726933439cd12c16bef8d
MD5 4a5689083086cd845f4390ab8b88b49b
BLAKE2b-256 e0a0044e7e5ebfa833e3dc76caead1484a0f560f709f8f9f8e0f7810d814e9f4

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3315920f60e38c2833f78665e8f664505b62742fe6074f7642d8b3e99b1a3623
MD5 24c3629c916a00497d9698b3b894d811
BLAKE2b-256 9666460edd27eefaaa4c7b2f3c80e9f73ce5265cdf13f7951e1b80102f103f73

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 ce7f09f1d7e895be02ce37c0fac36a10ba446f8ea9be23a9fd4b4c56c718e94b
MD5 4ee2f59fa6f96da4c9c083e3ed37e994
BLAKE2b-256 0f34f71b8f80896721dbeda86785ae562663738a5f04bacc2730d3327b519aa6

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: turbotext-0.3.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 196.6 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 21d26ac58737ff7c83d76c703c30f671be6c7ce7e51ca6018dcb983f9396a684
MD5 f76f5ca3c607b8b135c9937309909492
BLAKE2b-256 a54100a65f3a73c96a6077e3c2ccb434161d18ede09c0f30f4c3e5257b7fdc92

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2ff714c906774c0bba22ef7280dbc87f16671c980da57d7433a1c73f31671d16
MD5 30b655a2984334ddcda7296b5b687cec
BLAKE2b-256 8ad1d3c5f0a81aed5cac92855168c307fb1cd8fec52e59216cb2e123ef64a7fe

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c4cd5c0c351df05d20d8c3ee4b3f9e4ea9a83661328b72ebfa7a6cf2c2e92e64
MD5 f9bf91a1c5582b375b239b064c1bf8ec
BLAKE2b-256 8022b2c2ac523e8f45e944f53e4a0ec4ad233dadc0afd9d11984343c47f40faa

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e1dfd947313baa56f1cc1cb441e8a675493e5a3d99e491eb5962cff3b5189f2b
MD5 3d77667f354e463390ad5f8ca87e3f98
BLAKE2b-256 be4c0ff5d0d9a01125fbe3d9a3ee2e97a98684abbe34de48a7ba958bc7e17724

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7379de7794ab9105bdd8dffaa16ffce9f01a182627b0bd315d11a3f9ef7ad89d
MD5 a476fdf1a309680e1d48b81e6ab9ff2f
BLAKE2b-256 09c18c463eecda4717c65a2853d654a4ef5968be141f1b492604b2c2e81c4bc7

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a370cd0c669a59e0877e60b7105a34e16be8e77415fce94d98305a6b28f5a943
MD5 5fe93b712d7215dabd419c331bbbb6df
BLAKE2b-256 47aebb660901e48be505d4198adee84cdd68c87bf5fd20cbcc8c181070b674e4

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 47b7df18c5beaa8470420367d3eed991cde8054fe6c697d094bbb3ba0e681368
MD5 3aba2a464cad2b153cf5704080732578
BLAKE2b-256 3b642c7c8f4d0ce39f80920d782ea869acd74dc3c575090999d34fbe14df4b1e

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: turbotext-0.3.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 196.6 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 9268688dbf03086afe43ba21804fc2bb1019959e6ca1c3c231150d594cfc5f33
MD5 be4d5ebb120698ba02fd763e071b3a7c
BLAKE2b-256 5a62857cb80bf8c4219e9dc598827d87083619cff0af8893ffdb36cdd8263c76

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 626f28bc24ab8f5f6e1dca710479d44cdca54207b951a2ae2531e8a22b8afc6f
MD5 b97419900eeec8ebfe38ecfeccb048d6
BLAKE2b-256 f8026f8f807d8dcabf8e8552029e5d3f0bac5833b1cfab6d4266a1f93bf6d1c0

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 293be5c8484e1b7d355b1ea12df952640e8bbc48e540445fca16458737f9322c
MD5 103a2f6fba978666c80b1555cbea34b9
BLAKE2b-256 ee21be1d752b4a7b0529b47565c85960a24342551da44acf2c17cfe2cc86d628

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fb35d62a4ca2151237dd6423831c47437366b6b9fa35e6d22c453ebaa3e83aa9
MD5 ae493fdc0097ad4724c45b7ac892bceb
BLAKE2b-256 be6da167103a24ab59e9c7754b01ef13c3cd8382b33225249342d677691fba1a

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 79093c0dd5fcec4ab2baa6cf8333bad4ceb1368bbd22be54a86058425885200f
MD5 1d41e58c8a0d7441acb10db9fe9257b6
BLAKE2b-256 1a77b4c2074186d303bc61fd3deb7cbd9fc3cc28a7024b4909c2b1d9b22b9ec9

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a15142e078bb93c2ea5e12b8c55633866fdac46add78f76c10c0d81346d778f7
MD5 30e23976703aaee6094b08b2faccd3ed
BLAKE2b-256 4cda76d331b1ff3f37dae88b63c9fff3d862f2e597fd49539212e4715cdcdd8e

See more details on using hashes here.

File details

Details for the file turbotext-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for turbotext-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 acbce8cca5b3ffd9a1b5f7a1a301c83be0afe4a26128b8517a0d10981668e7f6
MD5 7cd3d983a3573b4f3d1577fa0404a287
BLAKE2b-256 4afd78efea86ef7e31f8eed13809d2f2288d8ab7163a4ec11b90e4ccf21ab2f0

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

29 files

0.2.0

29 files

0.1.0

29 files

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