{"id":2033,"library":"flexcache","title":"Flexcache: Disk-based object caching","description":"flexcache is a Python library (current version 0.3) designed to cache transformed versions of source objects to disk. It provides a robust and extensible framework for managing expensive calculations by storing their results persistently. The library allows for flexible cache invalidation strategies based on file modification time or content hash. It is currently in a pre-1.0 release, suggesting an active development cadence with potential for future changes.","status":"active","version":"0.3","language":"en","source_language":"en","source_url":"https://github.com/hgrecco/flexcache","tags":["caching","disk-cache","performance","serialization","data-processing","utility"],"install":[{"cmd":"pip install flexcache","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Type hinting utilities, likely for compatibility across Python versions or advanced type features.","package":"typing_extensions","optional":false}],"imports":[{"note":"Commonly used for caching where invalidation is based on file modification time.","symbol":"DiskCacheByMTime","correct":"from flexcache import DiskCacheByMTime"},{"note":"Used when cache invalidation requires detecting changes via file content hash, offering stronger integrity checks than modification time.","symbol":"DiskCacheByHash","correct":"from flexcache import DiskCacheByHash"},{"note":"Base class for implementing custom disk caching logic.","symbol":"DiskCache","correct":"from flexcache import DiskCache"}],"quickstart":{"code":"import pathlib\nfrom flexcache import DiskCacheByMTime\n\n# Create a cache directory (ensure it exists)\ncache_dir_path = pathlib.Path(os.environ.get('FLEXCACHE_CACHE_DIR', './my_flexcache_cache'))\ncache_dir_path.mkdir(parents=True, exist_ok=True)\n\ndc = DiskCacheByMTime(cache_folder=cache_dir_path)\n\ndef expensive_parser(source_path: pathlib.Path) -> str:\n    \"\"\"Simulates an expensive operation that reads and transforms a file.\"\"\"\n    print(f\"[Parser] Reading and processing: {source_path}\")\n    return source_path.read_text().upper()\n\n# Create a dummy source file\nsource_file_path = pathlib.Path(\"source.txt\")\nsource_file_path.write_text(\"Hello, Flexcache World!\")\n\n# First call: `expensive_parser` will be executed and result cached\nprint(\"\\n--- First call ---\")\nparsed_content_1 = dc.load(source_file_path, reader=expensive_parser)\nprint(f\"Result: {parsed_content_1}\")\n\n# Second call: result will be loaded from cache without executing `expensive_parser`\nprint(\"\\n--- Second call (from cache) ---\")\nparsed_content_2 = dc.load(source_file_path, reader=expensive_parser)\nprint(f\"Result: {parsed_content_2}\")\n\n# Modify the source file to invalidate the cache (for DiskCacheByMTime)\nsource_file_path.write_text(\"UPDATED content for Flexcache!\")\n\n# Third call: `expensive_parser` will be re-executed due to source modification\nprint(\"\\n--- Third call (cache invalidated) ---\")\nparsed_content_3 = dc.load(source_file_path, reader=expensive_parser)\nprint(f\"Result: {parsed_content_3}\")\n\n# Clean up generated files and directory\nsource_file_path.unlink()\nfor item in cache_dir_path.iterdir():\n    if item.is_file():\n        item.unlink()\ncache_dir_path.rmdir()","lang":"python","description":"This quickstart demonstrates how to initialize a `DiskCacheByMTime` instance, define an expensive 'reader' function, and use the `load` method to automatically cache and retrieve transformed data. It also shows how modifications to the source object invalidate the cache, triggering a re-execution of the reader. Ensure `os` is imported for the quickstart to correctly handle environment variables for cache directory paths."},"warnings":[{"fix":"Only use `flexcache` with trusted input sources for cached data. For sensitive applications, consider implementing a custom cache (subclassing `DiskCache`) with a safer serialization method like JSON or a custom binary format for trusted, known data types.","message":"The library uses Python's `pickle` protocol for serialization of cached objects. Deserializing data from an untrusted source using `pickle` can lead to arbitrary code execution. Ensure that cached files are only loaded from trusted sources or implement custom, secure serialization.","severity":"gotcha","affected_versions":"0.1.0 - 0.3.0"},{"fix":"If the integrity of cached data is paramount and source files might change without MTime updates, use `DiskCacheByHash`. Otherwise, `DiskCacheByMTime` offers better performance for frequently updated files.","message":"Choosing the correct cache invalidation strategy (`DiskCacheByMTime` vs. `DiskCacheByHash`) is crucial. `DiskCacheByMTime` relies on file modification timestamps, which might not detect changes if a file's content is altered without updating its timestamp (e.g., atomic writes that replace the file).","severity":"gotcha","affected_versions":"0.1.0 - 0.3.0"},{"fix":"Pin the `flexcache` version in your `requirements.txt` (e.g., `flexcache==0.3.0`) and review release notes thoroughly before upgrading to any new minor version.","message":"As `flexcache` is in a pre-1.0 version (0.3), its API and internal behavior may not be fully stable. Future minor releases (e.g., 0.4, 0.5) might introduce breaking changes without strict adherence to semantic versioning until a 1.0 release.","severity":"breaking","affected_versions":"<1.0.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}