{"id":49849750,"url":"https://github.com/arioch3131/omni-cache","last_synced_at":"2026-05-14T14:33:47.357Z","repository":{"id":350719328,"uuid":"1170092594","full_name":"arioch3131/omni-cache","owner":"arioch3131","description":"Unified Python cache and object-pool manager with pluggable backends, routing, async support, and production-ready decorators.","archived":false,"fork":false,"pushed_at":"2026-05-06T21:17:16.000Z","size":519,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T23:28:29.662Z","etag":null,"topics":["asyncio","backend","cache","caching","decorators","in-memory-cache","library","memcached","object-pool","observability","performance","redis","routing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arioch3131.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-01T17:31:41.000Z","updated_at":"2026-05-06T21:15:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/arioch3131/omni-cache","commit_stats":null,"previous_names":["arioch3131/omni-cache"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/arioch3131/omni-cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arioch3131%2Fomni-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arioch3131%2Fomni-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arioch3131%2Fomni-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arioch3131%2Fomni-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arioch3131","download_url":"https://codeload.github.com/arioch3131/omni-cache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arioch3131%2Fomni-cache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33029049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","backend","cache","caching","decorators","in-memory-cache","library","memcached","object-pool","observability","performance","redis","routing"],"created_at":"2026-05-14T14:33:42.660Z","updated_at":"2026-05-14T14:33:47.349Z","avatar_url":"https://github.com/arioch3131.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Omni-Cache\n\n**Universal cache and pool manager with pluggable backends**\n\nOmni-Cache is a comprehensive caching and object pooling library that provides a unified interface for multiple backends, intelligent routing, and production-ready features. Whether you need simple function memoization or enterprise-grade distributed caching, Omni-Cache scales with your needs.\n\n## Important Notice\n\n**This is a personal project.** While the code is provided as-is and functional, please note:\n- There will be **limited to no ongoing maintenance** of this project\n- You are **free to fork** this repository and adapt it to your needs\n- All usage must comply with the **MIT license** (see [LICENSE](LICENSE))\n\nFeel free to use, modify, and distribute this code according to the license terms.\nExternal changes are not actively managed and may not be reviewed or merged.\n\n## Overview\n\nOmni-Cache follows a modular architecture similar to SmartPool, with clear separation between core services, adapter implementations, and user-facing utilities.\n\n## Features\n\n- **Multiple Backends**: Memory, Redis, Memcached, AdaptiveMemoryPool, and custom adapters\n- **Unified Interface**: Single API for all cache and pool operations\n- **Intelligent Routing**: Namespace-based routing with automatic fallback\n- **Comprehensive Monitoring**: Built-in statistics, health checks, and performance metrics\n- **Hot-Reloadable Configuration**: YAML, JSON, TOML, and environment variable support\n- **Production-Ready Decorators**: `@cached`, `@pooled`, `@memoize` with advanced features\n- **Async Support**: Full async/await compatibility\n- **Type Safety**: Complete type hints and runtime validation\n- **Enterprise Features**: Connection pooling, retry logic, circuit breakers\n\n## When Should You Use This?\n\n### Perfect For\n- High-throughput APIs with repeated expensive reads\n- Multi-backend systems (in-memory + Redis + pooled resources)\n- Services that need observability on cache/pool behavior\n- Projects requiring routing and centralized cache configuration\n\n### Probably Overkill For\n- Small scripts with minimal recomputation cost\n- Single-threaded workloads with low cache churn\n- Short-lived one-off jobs where setup overhead dominates\n\n### Rule of Thumb\nIf your application repeatedly computes or fetches costly values and you need operational control (routing, monitoring, retries), Omni-Cache is a good fit.\n\n## Installation\n\n```bash\n# Basic installation\npip install omni_cache\n\n# With Redis support\npip install omni_cache[redis]\n\n# With all optional dependencies\npip install omni_cache[all]\n```\n\n## Quick Start\n\n### Ultra-Simple Usage\n\n```python\nfrom omni_cache import cached\n\n@cached(ttl=300)  # Cache for 5 minutes\ndef expensive_function(x, y):\n    # This will only run once per unique (x, y) combination\n    return complex_computation(x, y)\n\n# Use it normally\nresult = expensive_function(1, 2)  # Computed and cached\nresult = expensive_function(1, 2)  # Retrieved from cache\n```\n\n### Quick Setup\n\n```python\nfrom omni_cache import setup, cached\n\n# One-line setup with auto-discovery\nmanager = setup(auto_discover=True)\n\n@cached(ttl=300, namespace=\"api\")\ndef fetch_user_data(user_id):\n    return requests.get(f\"/api/users/{user_id}\").json()\n```\n\n## Basic Usage\n\n### Function Caching\n\n```python\nfrom omni_cache import cached, memoize, timed_cache\n\n# Basic caching with TTL\n@cached(ttl=300, namespace=\"database\")\ndef get_user(user_id):\n    return database.query(\"SELECT * FROM users WHERE id = ?\", user_id)\n\n# Simple memoization\n@memoize(maxsize=1000)\ndef fibonacci(n):\n    if n \u003c 2: return n\n    return fibonacci(n-1) + fibonacci(n-2)\n\n# Time-based caching\n@timed_cache(seconds=60)\ndef get_current_weather():\n    return weather_api.get_current()\n\n# Cache management\nget_user.invalidate(123)        # Invalidate specific call\nget_user.invalidate_all()       # Clear all cached results\nstats = get_user.cache_info()   # Get cache statistics\n```\n\n### Object Pooling\n\n```python\nfrom omni_cache import pooled\n\n@pooled(adapter=\"db_pool\", timeout=5.0, max_retries=3)\ndef query_database(connection, query, params):\n    # Connection automatically borrowed and returned\n    return connection.execute(query, params).fetchall()\n\n# Context manager for manual control\nfrom omni_cache import get_global_manager\n\nmanager = get_global_manager()\nwith manager.borrow(adapter=\"db_pool\") as connection:\n    result = connection.execute(\"SELECT 1\").fetchone()\n    # Connection automatically returned to pool\n```\n\n### Direct Manager Usage\n\n```python\nfrom omni_cache import get_global_manager\n\nmanager = get_global_manager()\n\n# Cache operations\nmanager.set(\"user:123\", user_data, ttl=300)\nuser = manager.get(\"user:123\")\nexists = manager.exists(\"user:123\")\nmanager.delete(\"user:123\")\n\n# Batch operations\nusers = manager.get_many([\"user:123\", \"user:456\"])\nmanager.set_many({\"user:789\": data1, \"user:101\": data2}, ttl=300)\n\n# Pool operations\nobj = manager.get(timeout=5.0, adapter=\"pool\")\nmanager.put(obj, adapter=\"pool\")\n```\n\n## Advanced Usage\n\n### Multi-Backend Setup\n\n```python\nfrom omni_cache import CacheManager, create_adapter, CacheBackend\n\n# Create manager\nmanager = CacheManager()\n\n# Add memory cache for hot data\nmemory_adapter = create_adapter(CacheBackend.MEMORY, {\n    \"max_size\": 10000,\n    \"eviction_policy\": \"lru\"\n})\nmanager.register_adapter(\"fast\", memory_adapter)\n\n# Add Redis for persistent cache\nredis_adapter = create_adapter(CacheBackend.REDIS, {\n    \"host\": \"localhost\",\n    \"port\": 6379,\n    \"db\": 0\n})\nmanager.register_adapter(\"persistent\", redis_adapter)\n\n# Add SmartPool for database connections\ndef create_db_connection():\n    return psycopg2.connect(DATABASE_URL)\n\npool_adapter = create_adapter(CacheBackend.SMARTPOOL, {\n    \"factory_function\": create_db_connection,\n    \"initial_size\": 5,\n    \"max_size\": 20\n})\nmanager.register_adapter(\"db_pool\", pool_adapter)\n```\n\n### Intelligent Routing\n\n```python\n# Set up routing rules\nmanager.add_routing_rule(\"cache\", \"fast\")        # cache:* → memory\nmanager.add_routing_rule(\"store\", \"persistent\")  # store:* → redis\nmanager.add_routing_rule(\"session\", \"fast\")      # session:* → memory\n\n# Automatic routing based on key patterns\nmanager.set(\"cache:temp_data\", data)      # → fast (memory)\nmanager.set(\"store:user_profile\", user)   # → persistent (redis)\nmanager.set(\"session:abc123\", session)    # → fast (memory)\n\n# Use with decorators\n@cached(ttl=60, namespace=\"cache\")     # → routed to memory\ndef get_temporary_data():\n    return generate_temp_data()\n\n@cached(ttl=3600, namespace=\"store\")   # → routed to redis\ndef get_user_profile(user_id):\n    return database.get_user(user_id)\n```\n\n### Configuration-Driven Setup\n\n```yaml\n# config.yaml\nglobal:\n  log_level: \"INFO\"\n  enable_routing: true\n  default_cache_adapter: \"redis\"\n  health_check_interval: 60\n\nadapters:\n  memory:\n    backend: \"memory\"\n    enabled: true\n    extra_config:\n      max_size: 10000\n      eviction_policy: \"lru\"\n  \n  redis:\n    backend: \"redis\"\n    enabled: true\n    extra_config:\n      host: \"localhost\"\n      port: 6379\n      db: 0\n  \n  db_pool:\n    backend: \"smartpool\"\n    enabled: true\n    extra_config:\n      initial_size: 5\n      max_size: 20\n      factory_function: \"myapp.database.create_connection\"\n```\n\n```python\nfrom omni_cache import ConfigManager, CacheManager\n\n# Load configuration\nconfig_manager = ConfigManager(\"config.yaml\")\nconfig_manager.enable_hot_reload()  # Auto-reload on file changes\n\n# Create manager from configuration\nmanager = setup(config_file=\"config.yaml\", enable_hot_reload=True)\n\n# Configuration is automatically applied\n@cached(ttl=300)  # Uses configured routing and backends\ndef my_function():\n    return expensive_operation()\n```\n\n## Configuration\n\n### Configuration Files\n\nOmni-Cache supports YAML, JSON, and TOML configuration files:\n\n```yaml\n# omni_cache.yaml\nglobal:\n  log_level: \"INFO\"\n  default_cache_adapter: \"memory\"\n  enable_routing: true\n  namespace_separator: \":\"\n  health_check_interval: 60.0\n  debug_mode: false\n\nadapters:\n  memory:\n    backend: \"memory\"\n    enabled: true\n    auto_connect: true\n    extra_config:\n      max_size: 10000\n      default_ttl: 3600\n      eviction_policy: \"lru\"\n      cleanup_interval: 60\n  \n  redis:\n    backend: \"redis\"\n    enabled: true\n    extra_config:\n      host: \"localhost\"\n      port: 6379\n      db: 0\n      password: null\n      socket_timeout: 5.0\n      connection_pool_max_connections: 10\n```\n\n### Environment Variables\n\n```bash\n# Global settings\nexport OMNI_CACHE_LOG_LEVEL=DEBUG\nexport OMNI_CACHE_DEFAULT_CACHE_ADAPTER=redis\nexport OMNI_CACHE_ENABLE_ROUTING=true\n\n# Adapter settings\nexport OMNI_CACHE_ADAPTERS_REDIS_EXTRA_CONFIG_HOST=redis.example.com\nexport OMNI_CACHE_ADAPTERS_REDIS_EXTRA_CONFIG_PORT=6380\n\n# Auto-setup\nexport OMNI_CACHE_AUTO_SETUP=true\n```\n\n### Programmatic Configuration\n\n```python\nfrom omni_cache import ConfigManager, GlobalConfig, AdapterConfig\n\n# Create configuration manager\nconfig_manager = ConfigManager()\n\n# Update global configuration\nconfig_manager.update_global_config({\n    \"log_level\": \"DEBUG\",\n    \"enable_routing\": True\n})\n\n# Add adapter configuration\nconfig_manager.add_adapter_config(\"redis\", {\n    \"backend\": \"redis\",\n    \"enabled\": True,\n    \"extra_config\": {\n        \"host\": \"redis.example.com\",\n        \"port\": 6379\n    }\n})\n\n# Hot reload from file\nconfig_manager.load_config(\"new_config.yaml\")\n```\n\n## Available Backends\n\n### Memory (Built-in)\n- **No dependencies**: Always available\n- **Features**: LRU/FIFO/Random eviction, TTL support, size limits\n- **Use case**: Single-process caching, development, testing\n\n```python\nmemory_adapter = create_adapter(CacheBackend.MEMORY, {\n    \"max_size\": 10000,\n    \"eviction_policy\": \"lru\",\n    \"default_ttl\": 3600\n})\n```\n\n### Redis (Optional)\n- **Dependency**: `pip install redis`\n- **Features**: Distributed caching, persistence, pub/sub\n- **Use case**: Multi-process/server caching, session storage\n\n```python\nredis_adapter = create_adapter(CacheBackend.REDIS, {\n    \"host\": \"localhost\",\n    \"port\": 6379,\n    \"db\": 0,\n    \"password\": \"secret\"\n})\n```\n\n### SmartPool (Optional)\n- **Dependency**: The `smartpool` package  \n- **Features**: Dynamic sizing, object lifecycle management, adaptive pooling\n- **Use case**: Database connections, expensive object pooling\n\n```python\ndef create_connection():\n    return psycopg2.connect(DATABASE_URL)\n\npool_adapter = create_adapter(CacheBackend.SMARTPOOL, {\n    \"factory_function\": create_connection,\n    \"initial_size\": 5,\n    \"max_size\": 20,\n    \"min_size\": 2\n})\n```\n\n### Custom Backends\nCreate your own adapters by implementing the appropriate base class:\n\n```python\nfrom omni_cache.adapters.base import BaseCacheAdapter\n\nclass MyCustomAdapter(BaseCacheAdapter):\n    def _do_connect(self) -\u003e bool:\n        # Implementation\n        return True\n    \n    def _do_disconnect(self) -\u003e bool:\n        # Implementation\n        return True\n    \n    def _do_health_check(self) -\u003e bool:\n        # Implementation\n        return True\n    \n    def _set_internal(self, key: str, value: Any, ttl: Optional[int] = None) -\u003e bool:\n        # Your cache set implementation\n        return True\n    \n    def _get_internal(self, key: str) -\u003e Any:\n        # Your cache get implementation\n        return None\n    \n    def _delete_internal(self, key: str) -\u003e bool:\n        # Your cache delete implementation\n        return True\n    \n    def _clear_internal(self) -\u003e bool:\n        # Your cache clear implementation\n        return True\n```\n\n### Adapter Scaffold Script\nFor simple adapters, you can generate a full boilerplate with:\n\n```bash\npython scripts/new_adapter.py my_backend --dependency my-lib\n```\n\nThis generates:\n- `src/omni_cache/adapters/my_backend/{__init__.py,config.py,my_backend.py,factory.py}`\n- `tests/unit/adapters/my_backend/{test_my_backend_config.py,test_my_backend_factory.py,test_my_backend_adapter.py}`\n\nThen complete the integration by:\n1. Exporting the adapter in `src/omni_cache/adapters/__init__.py`\n2. Registering the factory in `src/omni_cache/core/factories/factory_registry.py`\n3. Exporting the factory in `src/omni_cache/core/factories/__init__.py`\n4. Adding dependency and entry point in `pyproject.toml`\n\n## Monitoring and Statistics\n\n### Cache Statistics\n\n```python\nfrom omni_cache import get_global_manager\nfrom omni_cache.utils.decorators import get_cache_stats\n\n# Function-level statistics\n@cached(ttl=300)\ndef my_function():\n    return expensive_operation()\n\nstats = my_function.cache_info()\nprint(f\"Hit rate: {stats['hit_rate']:.2%}\")\n\n# Manager-level statistics\nmanager = get_global_manager()\nglobal_stats = manager.get_global_stats()\nprint(f\"Total hits: {global_stats['cache'].hits}\")\nprint(f\"Total misses: {global_stats['cache'].misses}\")\n\n# Adapter-specific statistics\nredis_stats = manager.get_adapter_stats(\"redis\")\n```\n\n### Health Monitoring\n\n```python\n# Health checks\nmanager = get_global_manager()\n\n# Check specific adapter\nredis_adapter = manager.get_adapter(\"redis\")\nis_healthy = redis_adapter.health_check()\n\n# Get backend information\ninfo = redis_adapter.get_backend_info()\nprint(f\"Connection state: {info['state']}\")\nprint(f\"Last health check: {info['last_health_check']}\")\n\n# Global health monitoring runs automatically\n# Check logs for health status updates\n```\n\n### Performance Profiling\n\n```python\n# Enable detailed logging and profiling\nfrom omni_cache import setup\n\nmanager = setup(\n    config_file=\"config.yaml\",\n    log_level=\"DEBUG\"  # Shows detailed operation logs\n)\n\n# Use profile_operations in configuration\nglobal_config = {\n    \"profile_operations\": True,\n    \"enable_detailed_logging\": True\n}\n```\n\n## Decorator Features\n\n### Advanced Caching Options\n\n```python\nfrom omni_cache import cached, cache_key\n\n# Custom key generation\n@cache_key(lambda user_id, include_inactive: f\"user:{user_id}:active:{not include_inactive}\")\n@cached(ttl=300)\ndef get_user_data(user_id, include_inactive=False):\n    return database.get_user(user_id, include_inactive)\n\n# Ignore specific arguments\n@cached(\n    ttl=300,\n    ignore_args={0},           # Ignore first argument (self)\n    ignore_kwargs={\"debug\"}    # Ignore debug flag\n)\ndef process_data(self, data, debug=False):\n    return expensive_processing(data)\n\n# Custom serialization\nimport pickle\n\n@cached(\n    ttl=300,\n    serializer=pickle.dumps,\n    deserializer=pickle.loads\n)\ndef get_complex_object():\n    return ComplexObject()\n\n# Event callbacks\n@cached(\n    ttl=300,\n    on_hit=lambda key, value: logger.info(f\"Cache hit: {key}\"),\n    on_miss=lambda key: logger.info(f\"Cache miss: {key}\"),\n    on_error=lambda exc: logger.error(f\"Cache error: {exc}\")\n)\ndef monitored_function():\n    return get_data()\n```\n\n### Retry Logic with Caching\n\n```python\nfrom omni_cache import retry_with_cache\n\n@retry_with_cache(\n    max_retries=3,\n    retry_delay=1.0,\n    exponential_backoff=True,\n    cache_failures=True,     # Cache failures to avoid repeated attempts\n    failure_ttl=60          # Cache failures for 60 seconds\n)\ndef unreliable_api_call():\n    response = requests.get(\"https://unreliable-api.com/data\")\n    return response.json()\n```\n\n### Async Support\n\n```python\nfrom omni_cache import async_cached\nimport aiohttp\n\n@async_cached(ttl=300, namespace=\"api\")\nasync def fetch_data(url):\n    async with aiohttp.ClientSession() as session:\n        async with session.get(url) as response:\n            return await response.json()\n\n# Usage\ndata = await fetch_data(\"https://api.example.com/data\")\n```\n\n## Utilities\n\n### Cache Management\n\n```python\nfrom omni_cache.utils.decorators import clear_cache, invalidate_cache\n\n# Clear by namespace\ncleared_count = clear_cache(namespace=\"user_data\")\n\n# Invalidate by pattern\ninvalidate_cache(pattern=\"user:*\")\n\n# Clear specific adapter\nclear_cache(adapter=\"redis\")\n\n# Clear everything\nclear_cache()\n```\n\n### Discovery and Information\n\n```python\nfrom omni_cache import discover_backends, get_version_info, info\n\n# See available backends\nbackends = discover_backends()\nprint(f\"Available: {list(backends.keys())}\")\n\n# Version information\nversion_info = get_version_info()\nprint(f\"Version: {version_info['version']}\")\nprint(f\"Redis support: {version_info['capabilities']['redis_adapter']}\")\n\n# Print detailed information\ninfo()  # Prints comprehensive system info\n```\n\n## Real-World Examples\n\n### Web Application Cache\n\n```python\nfrom flask import Flask\nfrom omni_cache import setup, cached, pooled\n\napp = Flask(__name__)\n\n# Setup caching\nsetup(config_file=\"web_cache.yaml\", auto_discover=True)\n\n@cached(ttl=300, namespace=\"api\")\ndef get_user_profile(user_id):\n    return database.get_user_profile(user_id)\n\n@cached(ttl=60, namespace=\"analytics\")\ndef get_page_stats():\n    return analytics.get_daily_stats()\n\n@pooled(adapter=\"db_pool\", timeout=5.0)\ndef execute_query(connection, query, params):\n    return connection.execute(query, params).fetchall()\n\n@app.route('/users/\u003cint:user_id\u003e')\ndef user_profile(user_id):\n    profile = get_user_profile(user_id)\n    return jsonify(profile)\n```\n\n### Data Processing Pipeline\n\n```python\nfrom omni_cache import cached, memoize, get_global_manager\nimport pandas as pd\n\n# Setup manager with multiple backends\nmanager = setup(config_file=\"pipeline.yaml\")\n\n@cached(ttl=3600, namespace=\"raw_data\", adapter=\"persistent\")\ndef load_dataset(filename):\n    \"\"\"Cache expensive data loading operations\"\"\"\n    return pd.read_csv(filename)\n\n@memoize(maxsize=1000)\ndef calculate_statistics(data_hash):\n    \"\"\"Memoize statistical calculations\"\"\"\n    return data.describe()\n\n@cached(ttl=1800, namespace=\"processed\", adapter=\"fast\")\ndef process_batch(batch_id):\n    \"\"\"Cache processed results\"\"\"\n    raw_data = load_dataset(f\"batch_{batch_id}.csv\")\n    return expensive_processing(raw_data)\n\n# Pipeline execution\nfor batch_id in range(100):\n    result = process_batch(batch_id)  # Cached on subsequent runs\n    stats = calculate_statistics(hash(str(result)))\n```\n\n### Microservices Communication\n\n```python\nfrom omni_cache import cached, async_cached, retry_with_cache\nimport aiohttp\n\n# Cache service responses\n@async_cached(ttl=300, namespace=\"service_a\")\nasync def call_service_a(endpoint, params):\n    async with aiohttp.ClientSession() as session:\n        async with session.get(f\"http://service-a/{endpoint}\", params=params) as response:\n            return await response.json()\n\n@retry_with_cache(max_retries=3, cache_failures=True, failure_ttl=60)\n@cached(ttl=60, namespace=\"service_b\")\ndef call_service_b(data):\n    response = requests.post(\"http://service-b/process\", json=data)\n    return response.json()\n\n# Circuit breaker pattern with cached fallbacks\n@cached(ttl=3600, namespace=\"fallback\")\ndef get_fallback_data(key):\n    return default_responses.get(key)\n\ndef resilient_service_call(key):\n    try:\n        return call_service_a(key)\n    except Exception:\n        return get_fallback_data(key)\n```\n\n## Documentation\n\nBuild the documentation locally:\n\n```bash\nbash scripts/build_docs.sh\n```\n\nOr with Sphinx directly:\n\n```bash\ncd docs\nmake html\n```\n\nGenerated docs are available in `docs/_build/html/`.\n\n## Examples\n\nExample programs are available in [`examples/`](examples/) with usage patterns for:\n- Web applications\n- Data processing pipelines\n- Microservice communication\n- Adapter and routing configurations\n\nStart with [`examples/README.md`](examples/README.md) for an index.\n\n## Testing\n\n### Test Configuration\n\n```python\n# test_config.yaml\nglobal:\n  log_level: \"DEBUG\"\n  default_cache_adapter: \"memory\"\n\nadapters:\n  memory:\n    backend: \"memory\"\n    enabled: true\n    extra_config:\n      max_size: 100  # Small cache for testing\n```\n\n### Unit Tests\n\n```python\nimport pytest\nfrom omni_cache import setup, cached, temporary_config\n\ndef test_caching():\n    # Setup test environment\n    setup(config_file=\"test_config.yaml\")\n    \n    call_count = 0\n    \n    @cached(ttl=60)\n    def test_function(x):\n        nonlocal call_count\n        call_count += 1\n        return x * 2\n    \n    # Test caching behavior\n    result1 = test_function(5)\n    result2 = test_function(5)\n    \n    assert result1 == result2 == 10\n    assert call_count == 1  # Function called only once\n\ndef test_with_temporary_config():\n    with temporary_config({\"debug_mode\": True}):\n        # Test with debug configuration\n        pass\n    # Original configuration restored\n```\n\n### Run Test Suites\n\n```bash\n# Unit tests\npytest tests/unit/\n\n# Integration tests\npytest tests/integration/\n\n# Performance tests\npytest tests/performance/\n```\n\n## Migration Guide\n\n### From functools.lru_cache\n\n```python\n# Before (functools)\nfrom functools import lru_cache\n\n@lru_cache(maxsize=128)\ndef expensive_function(x):\n    return complex_computation(x)\n\n# After (omni-cache)\nfrom omni_cache import memoize\n\n@memoize(maxsize=128)\ndef expensive_function(x):\n    return complex_computation(x)\n\n# Benefits: TTL support, statistics, invalidation, persistence\n```\n\n### From Redis Direct Usage\n\n```python\n# Before (direct Redis)\nimport redis\nr = redis.Redis()\n\ndef get_user(user_id):\n    key = f\"user:{user_id}\"\n    cached = r.get(key)\n    if cached:\n        return json.loads(cached)\n    \n    user = database.get_user(user_id)\n    r.setex(key, 300, json.dumps(user))\n    return user\n\n# After (omni-cache)\nfrom omni_cache import cached\n\n@cached(ttl=300, namespace=\"user\", adapter=\"redis\")\ndef get_user(user_id):\n    return database.get_user(user_id)\n\n# Benefits: Automatic serialization, routing, fallback, monitoring\n```\n\n## Project Maintenance Policy\n\nThere is no active maintenance process for this repository.\nIssues or pull requests may remain unanswered. If you need long-term evolution,\nforking is the recommended path.\n\n### Development Setup\n\n```bash\n# Navigate to project directory\ncd omni-cache\n\n# Create virtual environment\npython -m venv venv\nsource venv/bin/activate  # Linux/Mac\n# or\nvenv\\Scripts\\activate     # Windows\n\n# Install development dependencies\npip install -e .[dev]\n\n# Run tests\npytest\n\n# Run linting\nflake8 src/\nmypy src/\n\n# Run benchmarks (if available)\npython scripts/benchmark.py\n```\n\n## Project Structure\n\n```\nomni_cache/\n├── core/           # Core interfaces and manager\n├── adapters/       # Backend implementations\n├── utils/          # Decorators and utilities\n└── __init__.py     # Public API\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- Inspired by Django's cache framework\n- Built on the shoulders of Redis, Memcached, and other great projects\n- Thanks to all users\n\n## Resources\n\n- **Documentation**: See `docs/` directory and inline docstrings\n- **GitHub**: This repository\n- **Issues**: Please file issues in this repository\n- **Examples**: See `examples/` directory\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farioch3131%2Fomni-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farioch3131%2Fomni-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farioch3131%2Fomni-cache/lists"}