{"id":8981,"library":"expiring-dict","title":"Expiring Dict","description":"expiring-dict is a Python library that provides a dictionary-like object with Time-To-Live (TTL) support for its values, enabling automatic expiration of cached items. It is designed for simple caching scenarios where items need to be removed after a certain period. The library is currently active, with its latest version released in February 2025, and offers both dictionary-level and key-level expiration settings.","status":"active","version":"1.1.2","language":"python","source_language":"en","source_url":"https://github.com/dparker2/py-expiring-dict","tags":["caching","dictionary","ttl","expiration","cache","in-memory"],"install":[{"cmd":"pip install expiring-dict","lang":"bash","label":"Install using pip"}],"dependencies":[],"imports":[{"symbol":"ExpiringDict","correct":"from expiring_dict import ExpiringDict"}],"quickstart":{"code":"from expiring_dict import ExpiringDict\nimport time\n\n# Dictionary-level TTL: items expire after 1 second\ncache_dict_level = ExpiringDict(max_age_seconds=1)\ncache_dict_level[\"my_key\"] = \"my_value\"\nprint(f\"Initial value (dict-level): {cache_dict_level.get('my_key')}\")\ntime.sleep(1.5)\nprint(f\"Value after 1.5 seconds (dict-level): {cache_dict_level.get('my_key')}\") # Should be None\n\n# Key-level TTL: individual keys expire after specified seconds\ncache_key_level = ExpiringDict()\ncache_key_level[\"persistent_key\"] = \"this never expires by default\"\ncache_key_level.ttl(\"expiring_key\", \"this expires in 1 second\", 1)\n\nprint(f\"\\nPersistent value: {cache_key_level.get('persistent_key')}\")\nprint(f\"Expiring value (initial): {cache_key_level.get('expiring_key')}\")\ntime.sleep(1.5)\nprint(f\"Persistent value (after 1.5s): {cache_key_level.get('persistent_key')}\")\nprint(f\"Expiring value (after 1.5s): {cache_key_level.get('expiring_key')}\") # Should be None","lang":"python","description":"Demonstrates creating an ExpiringDict with a global TTL and setting individual TTLs for specific keys. Accessing an expired key returns None, and the key is removed."},"warnings":[{"fix":"Always access items with `cache.get(key)` or `cache[key]` to trigger expiration. If an accurate length or full cleanup is needed, consider manually calling `cache.cleanup()` (if available, check documentation for `expiring-dict`) or iterating through items with a `.get()` call on each.","message":"Iteration (e.g., `for key in cache` or `cache.keys()`) and checking length (`len(cache)`) do not automatically remove expired items. Expiration only occurs when an item is accessed (e.g., `cache['key']` or `cache.get('key')`). This can lead to seemingly 'stale' or inaccurate views of the dictionary content if not handled explicitly.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Avoid pickling ExpiringDict instances directly. If serialization is required, extract the raw data (e.g., `dict(cache.items_with_timestamp())` if applicable) and reconstruct the ExpiringDict after deserialization. Alternatively, consider a different caching solution if direct pickling of the cache object is a critical requirement.","message":"ExpiringDict objects may not be reliably picklable due to internal threading locks used for thread safety. Attempting to pickle an ExpiringDict can result in a `TypeError` related to unpicklable lock objects, making it difficult to serialize and deserialize the cache.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Initialize `ExpiringDict(max_age_seconds=None)` if you plan to manage expiration solely on a per-key basis. For keys with specific TTLs, use `cache.ttl(key, value, custom_age)`. Keys set via `cache[key] = value` will inherit the dictionary's `max_age_seconds` if set, or have no expiration if `max_age_seconds` is `None`.","message":"Setting `max_age_seconds` for the `ExpiringDict` applies to *all* keys in the dictionary by default. If you intend for some keys to have no expiration or a different expiration, you must explicitly use the `cache.ttl(key, value, age)` method or ensure `max_age_seconds` is `None` during initialization if you only want key-level TTLs.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'2025':62 'activ':54 'automat':28 'cach':31,38,75,79 'certain':48 'current':53 'design':35 'dict':2,5 'dictionari':14,67,76 'dictionary-level':66 'dictionary-lik':13 'enabl':27 'expir':1,4,29,73,78 'expiring-dict':3 'februari':61 'in-memori':80 'item':32,41 'key':71 'key-level':70 'latest':57 'level':68,72 'librari':9,51 'like':15 'live':21 'memori':82 'need':42 'object':16 'offer':64 'period':49 'provid':11 'python':8 'releas':59 'remov':45 'scenario':39 'set':74 'simpl':37 'support':23 'time':19 'time-to-l':18 'ttl':22,77 'valu':26 'version':58","created_at":"2026-04-16T18:47:51.585422+00:00","updated_at":"2026-04-16T18:47:51.585422+00:00","problems":[{"fix":"Always use `value = cache.get('key')` to safely retrieve values. This method returns `None` (or a specified default) if the key does not exist or has expired, preventing a `KeyError`.","cause":"Attempting to access an expired key using `cache['key']` instead of `cache.get('key')`. When a key expires, it's effectively removed, so direct access will raise a KeyError.","error":"KeyError: 'some_key'"},{"fix":"Do not attempt to pickle `ExpiringDict` objects directly. If you need to persist the cached data, extract the key-value pairs (and their timestamps if needed) into a standard dictionary or list of tuples, then pickle that data. Reconstruct the `ExpiringDict` from this data upon deserialization.","cause":"You are attempting to serialize an `ExpiringDict` instance using a module like `pickle` or `dill`. `ExpiringDict` uses internal threading locks for thread-safety, which are generally not picklable.","error":"TypeError: cannot pickle '_thread.lock' object"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.1.2","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/dparker2/py-expiring-dict","docs":null,"changelog":null,"pypi":"https://pypi.org/project/expiring-dict/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}