boltons
Boltons is a collection of more than 230 pure-Python utilities designed to feel like missing pieces of the standard library. Its independent modules cover iteration, recursive data transforms, dictionaries and multimaps, caches, atomic file writes, URLs, strings, time values, tracebacks, queues, functions, sockets, and more. You import only the module you need, or vendor that module into an application. It is a utility shelf, not a framework with one workflow or global configuration.
Boltons is a high-quality place to look after the standard library comes up short, especially for `remap`, atomic files, and custom mapping types. Import narrowly and resist making it the automatic answer to every three-line helper.
Use it if
- You repeatedly need a well-documented utility that the Python standard library still does not provide
- You want pure-Python, dependency-free helpers that work across CPython and PyPy
- You need practical tools such as recursive remapping, atomic saves, ordered multimaps, bounded caches, or structured URLs
- You may vendor a stable module into an application that cannot add the whole package as a dependency
- The standard library already covers your need clearly: adding a broad utility dependency for one call to `itertools.pairwise`, `functools.cached_property`, or `urllib.parse` gives future readers two vocabularies for the same job
- You need an advanced domain-specific implementation: the README says most modules aim to be good enough for basic use and directs advanced cases toward specialized third-party packages
- You expect one cohesive top-level API: utilities live in separate modules such as `iterutils`, `dictutils`, `cacheutils`, and `urlutils`, so importing from `boltons` itself is not the intended discovery path
- You need to minimize vendored maintenance: the README explicitly permits copying independent modules, but doing so makes your repository responsible for tracking upstream fixes and license notices
- Your team depends on static typing as the primary documentation and has not verified coverage for the selected modules: Boltons spans many dynamic utility APIs, callbacks, and custom containers, so check the installed type information against your strict checker before standardizing on it
Setup reality
`pip install boltons` is the whole installation: version 26.1.0 supports Python 3.7 through 3.14, includes no runtime dependencies, and is pure Python, so there are no compilers, services, credentials, or config files. The practical setup cost is API selection. Boltons contains more than 230 utilities, but they are intentionally split across modules; read the relevant module page and import the named helper rather than treating the package as a grab bag to wildcard-import. Check the standard library first because newer Python releases now include some ideas that once justified third-party helpers. Decide whether to depend on the package or vendor one independent module. A normal dependency receives upstream fixes but brings the complete distribution; vendorization keeps the installed graph flat but requires preserving the BSD license, recording the source version, and periodically comparing upstream changes. Several helpers have semantics worth reading before use: `chunked` materializes lists while iterator variants stream, JavaScript-style URL assumptions do not replace a security review, `cachedproperty` keeps the computed value on the instance, fixed-size caches do not become distributed caches, and `atomic_save` protects replacement of a local file but cannot make a sequence of external side effects transactional. Boltons uses calendar versioning, so pin or range releases according to your compatibility tests rather than interpreting 26 as a breaking major version.
Patterns
Split an iterable into chunkschunk-iterable
from boltons.iterutils import chunked
batches = chunked(range(10), 3)`chunked` returns a materialized list; use `chunked_iter` when the source or result is large.
Build overlapping windowsiterate-windows
from boltons.iterutils import windowed_iter
for previous, current, following in windowed_iter(values, 3):
process(previous, current, following)The iterator version avoids materializing every window, but each yielded window still reflects a fixed width.
Remove duplicates while preserving orderdeduplicate-in-order
from boltons.iterutils import unique
users = unique(records, key=lambda row: row['email'].lower())The key result must be hashable; the first item for each key is retained.
Remove secret keys recursivelytransform-nested-data
from boltons.iterutils import remap
clean = remap(
payload,
visit=lambda path, key, value: key not in {'password', 'token'},
)Returning false from `visit` drops that item; custom `enter` and `exit` callbacks are available for more complex container behavior.
Generate bounded exponential backoffgenerate-backoff-delays
from boltons.iterutils import backoff
delays = backoff(0.1, 5.0, count=8, factor=2.0, jitter=True)This only generates delay values; retry classification, sleeping, cancellation, and attempt logging remain application responsibilities.
Replace a text file atomicallysave-file-atomically
from boltons.fileutils import atomic_save
with atomic_save('settings.json', text_mode=True, overwrite=True) as stream:
stream.write(rendered_json)Atomic replacement protects one local destination file; it does not make several file or database writes one transaction.
Use a bounded least-recently-used mappingcreate-lru-cache
from boltons.cacheutils import LRU
cache = LRU(max_size=256)
cache['user:42'] = profile
profile = cache.get('user:42')This is an in-process mapping without cross-process sharing or persistent invalidation.
Compute an instance property oncecache-property
from boltons.cacheutils import cachedproperty
class Report:
@cachedproperty
def rows(self):
return load_expensive_rows()The result remains on that instance; delete the stored attribute deliberately if your object supports recomputation.
Keep ordered values for repeated keysstore-repeated-keys
from boltons.dictutils import OrderedMultiDict
headers = OrderedMultiDict()
headers.add('Set-Cookie', 'a=1')
headers.add('Set-Cookie', 'b=2')
all_cookies = headers.getlist('Set-Cookie')Normal item access returns one value; use multivalue methods such as `getlist` when duplicates are meaningful.
Create an ASCII URL slugcreate-url-slug
from boltons.strutils import slugify
slug = slugify('First post: café!', delim='-', ascii=True)Slug generation is normalization, not a uniqueness guarantee; add a stable identifier or collision check.
Parse a short human durationparse-duration
from boltons.timeutils import parse_timedelta
timeout = parse_timedelta('2 days 3.5 hours')This produces a `datetime.timedelta`; it is for durations, not calendar-aware dates or scheduling.
Distinguish missing from an explicit nullcreate-sentinel
from boltons.typeutils import make_sentinel
MISSING = make_sentinel('MISSING', var_name='MISSING')
def update(value=MISSING):
if value is MISSING:
return 'unchanged'
return valueUse identity checks with a sentinel; `var_name` gives it a useful representation and supports pickling expectations described in the docs.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| more-itertools | PyPI | Your missing helpers are specifically iterator recipes and you want a focused, widely used package |
| toolz | PyPI | You prefer composable functional utilities for iterators, mappings, currying, and pipelines |
| cachetools | PyPI | Caching is the real requirement and you need TTL, LFU, LRU, and decorator-focused choices |