zerda 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zerda/__init__.py +64 -0
- zerda/cache/__init__.py +30 -0
- zerda/cache/cache_entry.py +102 -0
- zerda/cache/cache_manager.py +711 -0
- zerda/cache/cache_metrics.py +124 -0
- zerda/cache/cache_strategies.py +9 -0
- zerda/cache/config_cache.py +284 -0
- zerda/cache/cost_model.py +287 -0
- zerda/cache/embedding_index.py +489 -0
- zerda/cache/metrics.py +301 -0
- zerda/cache/models.py +354 -0
- zerda/cache/multi_level_cache.py +978 -0
- zerda/cache/normalization.py +169 -0
- zerda/cache/policy_learner.py +227 -0
- zerda/cache/security.py +218 -0
- zerda/cache/storage/__init__.py +28 -0
- zerda/cache/storage/base_storage.py +38 -0
- zerda/cache/storage/factury_fun.py +24 -0
- zerda/cache/storage/redis.py +172 -0
- zerda/cache/storage/sqlite.py +150 -0
- zerda/cache/storage/storage_memory.py +64 -0
- zerda/cache/tenant_manager.py +269 -0
- zerda/chunks/__init__.py +92 -0
- zerda/chunks/adaptive_chunker.py +210 -0
- zerda/chunks/arabic_chunker.py +452 -0
- zerda/chunks/arabic_preprocessor.py +329 -0
- zerda/chunks/base.py +131 -0
- zerda/chunks/chunk_config.py +132 -0
- zerda/chunks/context_aware_chunker.py +233 -0
- zerda/chunks/deduplicator.py +118 -0
- zerda/chunks/doc_model.py +137 -0
- zerda/chunks/document_structure_parser.py +288 -0
- zerda/chunks/embeddings.py +182 -0
- zerda/chunks/metadata_enricher.py +187 -0
- zerda/chunks/multi_chunker.py +377 -0
- zerda/chunks/query_pattern_analyzer.py +176 -0
- zerda/chunks/semantic_chunker.py +165 -0
- zerda/chunks/structure_aware_chunker.py +231 -0
- zerda/chunks/text_splitter.py +210 -0
- zerda/context/__init__.py +168 -0
- zerda/context/config.py +143 -0
- zerda/context/engine.py +669 -0
- zerda/context/guard_and_learning.py +365 -0
- zerda/context/legacy_compat.py +146 -0
- zerda/context/models.py +291 -0
- zerda/context/pipeline.py +417 -0
- zerda/context/query_analyzer.py +237 -0
- zerda/context/retriever.py +609 -0
- zerda/context/strategy.py +149 -0
- zerda/document_loaders/__init__.py +102 -0
- zerda/document_loaders/auto_loader.py +192 -0
- zerda/document_loaders/base_loader.py +129 -0
- zerda/document_loaders/config_loader.py +193 -0
- zerda/document_loaders/csv_loader.py +286 -0
- zerda/document_loaders/directory_loader.py +208 -0
- zerda/document_loaders/docx_loader.py +143 -0
- zerda/document_loaders/graph_loader.py +430 -0
- zerda/document_loaders/html_loader.py +227 -0
- zerda/document_loaders/json_loader.py +260 -0
- zerda/document_loaders/pdf_loader.py +251 -0
- zerda/document_loaders/table_loader.py +547 -0
- zerda/document_loaders/text_loader.py +250 -0
- zerda/document_loaders/web_loader.py +169 -0
- zerda/embeddings/__init__.py +128 -0
- zerda/embeddings/arabic_embedder.py +887 -0
- zerda/embeddings/base_embedder.py +492 -0
- zerda/embeddings/config_embedder.py +44 -0
- zerda/embeddings/gemini_embedder.py +785 -0
- zerda/embeddings/hugginface_embedder.py +476 -0
- zerda/embeddings/mistral_embedder.py +596 -0
- zerda/embeddings/ollama_embedder.py +654 -0
- zerda/embeddings/openai_embedder.py +734 -0
- zerda/llm/__init__.py +47 -0
- zerda/llm/anthropic_interface.py +163 -0
- zerda/llm/base_llm_interface.py +130 -0
- zerda/llm/config_llm.py +29 -0
- zerda/llm/gemini_interface.py +334 -0
- zerda/llm/groq_interface.py +184 -0
- zerda/llm/mistral_interface.py +193 -0
- zerda/llm/ollama_interface.py +389 -0
- zerda/llm/openai_interface.py +163 -0
- zerda/llm/tools.py +188 -0
- zerda/memory/__init__.py +80 -0
- zerda/memory/agents/__init__.py +9 -0
- zerda/memory/agents/agent_memory.py +417 -0
- zerda/memory/core/__init__.py +18 -0
- zerda/memory/core/base.py +94 -0
- zerda/memory/core/config.py +147 -0
- zerda/memory/core/memory_entry.py +231 -0
- zerda/memory/core/memory_type.py +117 -0
- zerda/memory/core/models.py +56 -0
- zerda/memory/dashboard/__init__.py +21 -0
- zerda/memory/dashboard/__main__.py +4 -0
- zerda/memory/dashboard/app.py +427 -0
- zerda/memory/dashboard/static/app.js +396 -0
- zerda/memory/dashboard/static/index.html +114 -0
- zerda/memory/dashboard/static/style.css +626 -0
- zerda/memory/intelligent/__init__.py +24 -0
- zerda/memory/intelligent/forgetting_mechanism.py +145 -0
- zerda/memory/intelligent/memory_compressor.py +266 -0
- zerda/memory/intelligent/memory_manager.py +415 -0
- zerda/memory/intelligent/memory_selector.py +161 -0
- zerda/memory/intelligent/short_term_memory.py +85 -0
- zerda/memory/intelligent/user_profile_manager.py +241 -0
- zerda/memory/intelligent/working_memory.py +103 -0
- zerda/memory/memories/__init__.py +14 -0
- zerda/memory/memories/buffer_memory.py +106 -0
- zerda/memory/memories/entity_memory.py +217 -0
- zerda/memory/memories/summary_memory.py +192 -0
- zerda/memory/memories/window_memory.py +60 -0
- zerda/memory/rag/__init__.py +2 -0
- zerda/memory/rag/context_builder.py +223 -0
- zerda/memory/security/__init__.py +2 -0
- zerda/memory/security/privacy_security.py +233 -0
- zerda/memory/semantic_memory/__init__.py +2 -0
- zerda/memory/semantic_memory/semantic_memory.py +302 -0
- zerda/memory/storage/__init__.py +2 -0
- zerda/memory/storage/long_term_memory.py +237 -0
- zerda/observability/__init__.py +129 -0
- zerda/observability/exporters/__init__.py +12 -0
- zerda/observability/exporters/base.py +37 -0
- zerda/observability/exporters/console.py +48 -0
- zerda/observability/exporters/json.py +59 -0
- zerda/observability/exporters/langsmith.py +134 -0
- zerda/observability/span.py +191 -0
- zerda/observability/tracing.py +291 -0
- zerda/output_parser/__init__.py +76 -0
- zerda/output_parser/base_parser.py +255 -0
- zerda/output_parser/csv_parser.py +175 -0
- zerda/output_parser/fixer.py +338 -0
- zerda/output_parser/format_detector.py +280 -0
- zerda/output_parser/json_parser.py +180 -0
- zerda/output_parser/list_parser.py +182 -0
- zerda/output_parser/parser.py +658 -0
- zerda/output_parser/pydantic_parser.py +172 -0
- zerda/output_parser/retry_handler.py +307 -0
- zerda/output_parser/schema.py +269 -0
- zerda/output_parser/structured_parser.py +250 -0
- zerda/output_parser/validator.py +313 -0
- zerda/output_parser/yaml_parser.py +260 -0
- zerda/plugins/__init__.py +98 -0
- zerda/plugins/base_plugin.py +392 -0
- zerda/plugins/hot_reload.py +346 -0
- zerda/plugins/loader.py +227 -0
- zerda/plugins/metadata.py +306 -0
- zerda/plugins/plugin_manager.py +698 -0
- zerda/plugins/registry.py +225 -0
- zerda/plugins/security.py +303 -0
- zerda/plugins/types/__init__.py +35 -0
- zerda/plugins/types/action_plugin.py +52 -0
- zerda/plugins/types/processing_plugin.py +35 -0
- zerda/plugins/types/retrieval_plugin.py +42 -0
- zerda/plugins/types/tool_plugin.py +24 -0
- zerda/prompt/__init__.py +104 -0
- zerda/prompt/ab_testing.py +512 -0
- zerda/prompt/builder.py +144 -0
- zerda/prompt/context_manager.py +285 -0
- zerda/prompt/guardrails.py +328 -0
- zerda/prompt/optimizer.py +161 -0
- zerda/prompt/prompt_engine.py +541 -0
- zerda/prompt/strategies/__init__.py +425 -0
- zerda/prompt/templates.py +791 -0
- zerda/prompt/types.py +176 -0
- zerda/rag/__init__.py +24 -0
- zerda/rag/core/__init__.py +42 -0
- zerda/rag/core/base_rag_system.py +246 -0
- zerda/rag/core/document_versioning.py +510 -0
- zerda/rag/core/evaluation.py +640 -0
- zerda/rag/core/exceptions.py +459 -0
- zerda/rag/core/logger.py +282 -0
- zerda/rag/core/prompt_router.py +299 -0
- zerda/rag/core/query_expansion.py +241 -0
- zerda/rag/core/rag_config.py +137 -0
- zerda/rag/core/rag_system.py +793 -0
- zerda/rag/core/reranker.py +405 -0
- zerda/rag/core/retrieval_cache.py +146 -0
- zerda/rag/core/synonm_table.py +1232 -0
- zerda/rag/types/agentic_rag/__init__.py +10 -0
- zerda/rag/types/agentic_rag/action_step.py +15 -0
- zerda/rag/types/agentic_rag/agentic_config.py +45 -0
- zerda/rag/types/agentic_rag/agentic_rag.py +779 -0
- zerda/rag/types/agentic_rag/agentic_result.py +37 -0
- zerda/rag/types/agentic_rag/cache.py +33 -0
- zerda/rag/types/agentic_rag/document.py +23 -0
- zerda/rag/types/conversational_rag/__init__.py +11 -0
- zerda/rag/types/conversational_rag/conversation_config.py +28 -0
- zerda/rag/types/conversational_rag/conversation_history.py +179 -0
- zerda/rag/types/conversational_rag/conversation_turn.py +41 -0
- zerda/rag/types/conversational_rag/conversational_rag.py +364 -0
- zerda/rag/types/domain_rag/__init__.py +12 -0
- zerda/rag/types/domain_rag/domain_defination.py +210 -0
- zerda/rag/types/domain_rag/domain_metrics.py +30 -0
- zerda/rag/types/domain_rag/domain_specific_rag.py +626 -0
- zerda/rag/types/federated_rag/__init__.py +4 -0
- zerda/rag/types/federated_rag/circuitbreaker.py +60 -0
- zerda/rag/types/federated_rag/federat.py +1151 -0
- zerda/rag/types/federated_rag/federat_cache.py +39 -0
- zerda/rag/types/graph_rag/__init__.py +7 -0
- zerda/rag/types/graph_rag/config.py +142 -0
- zerda/rag/types/graph_rag/edges.py +135 -0
- zerda/rag/types/graph_rag/graph_rag.py +595 -0
- zerda/rag/types/graph_rag/knowledge_graph.py +330 -0
- zerda/rag/types/graph_rag/node.py +136 -0
- zerda/rag/types/hybrid_search/__init__.py +10 -0
- zerda/rag/types/hybrid_search/bm25.py +121 -0
- zerda/rag/types/hybrid_search/hybrid_search.py +680 -0
- zerda/rag/types/hybrid_search/hybrid_search_config.py +15 -0
- zerda/rag/types/hybrid_search/stanze_.py +143 -0
- zerda/rag/types/hybrid_search/tfidf.py +93 -0
- zerda/rag/types/multi_doc_rag/__init__.py +4 -0
- zerda/rag/types/multi_doc_rag/multi_doc_rag.py +637 -0
- zerda/rag/types/multi_hop/__init__.py +7 -0
- zerda/rag/types/multi_hop/multi_hop.py +703 -0
- zerda/rag/types/multi_hop/multihop_dataclass.py +29 -0
- zerda/rag/types/multi_hop/multihop_strategy.py +11 -0
- zerda/rag/types/multi_hop/query_decomposer.py +293 -0
- zerda/rag/types/self_improving_rag/__init__.py +24 -0
- zerda/rag/types/self_improving_rag/hyde.py +154 -0
- zerda/rag/types/self_improving_rag/recursive.py +183 -0
- zerda/rag/types/self_improving_rag/self_config.py +118 -0
- zerda/rag/types/self_improving_rag/self_improving_rag.py +389 -0
- zerda/rag/types/self_improving_rag/self_rag_dataclass.py +158 -0
- zerda/rag/types/streaming_rag/__init__.py +11 -0
- zerda/rag/types/streaming_rag/protocols.py +24 -0
- zerda/rag/types/streaming_rag/streaming_config.py +29 -0
- zerda/rag/types/streaming_rag/streaming_enum.py +9 -0
- zerda/rag/types/streaming_rag/streaming_rag.py +445 -0
- zerda/router/__init__.py +40 -0
- zerda/router/cache/__init__.py +3 -0
- zerda/router/cache/manager.py +215 -0
- zerda/router/config.py +159 -0
- zerda/router/core/__init__.py +7 -0
- zerda/router/core/base.py +221 -0
- zerda/router/core/result.py +193 -0
- zerda/router/core/route.py +284 -0
- zerda/router/core/route_group.py +285 -0
- zerda/router/execution/__init__.py +14 -0
- zerda/router/execution/executor.py +468 -0
- zerda/router/execution/streaming_executor.py +391 -0
- zerda/router/feedback/__init__.py +7 -0
- zerda/router/feedback/engine.py +271 -0
- zerda/router/observability/__init__.py +7 -0
- zerda/router/observability/observability.py +359 -0
- zerda/router/routing/__init__.py +15 -0
- zerda/router/routing/hierarchical.py +602 -0
- zerda/router/routing/pipeline.py +315 -0
- zerda/router/routing/scorers.py +342 -0
- zerda/vector_database/__init__.py +13 -0
- zerda/vector_database/base.py +360 -0
- zerda/vector_database/chroma.py +742 -0
- zerda/vector_database/faiss.py +966 -0
- zerda/vector_database/pinecone.py +1189 -0
- zerda-0.1.0.dist-info/METADATA +309 -0
- zerda-0.1.0.dist-info/RECORD +257 -0
- zerda-0.1.0.dist-info/WHEEL +5 -0
- zerda-0.1.0.dist-info/licenses/LICENSE +21 -0
- zerda-0.1.0.dist-info/top_level.txt +1 -0
zerda/__init__.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
zerda — Advanced Retrieval-Augmented Generation (RAG) Toolkit for Arabic & Multilingual LLM Apps
|
|
4
|
+
===================================================================================================
|
|
5
|
+
|
|
6
|
+
zerda is a modular, production-grade toolkit for building Retrieval-Augmented
|
|
7
|
+
Generation systems, with first-class support for Arabic text processing
|
|
8
|
+
alongside general multilingual use.
|
|
9
|
+
|
|
10
|
+
It bundles, as independent sub-packages that can be used together or on
|
|
11
|
+
their own:
|
|
12
|
+
|
|
13
|
+
zerda.rag High-level RAG systems (agentic, graph, hybrid,
|
|
14
|
+
multi-hop, multi-document, conversational,
|
|
15
|
+
federated, self-improving, streaming, domain RAG)
|
|
16
|
+
zerda.embeddings Embedding providers (OpenAI, Gemini, Mistral,
|
|
17
|
+
HuggingFace, Ollama, Arabic-specialized)
|
|
18
|
+
zerda.llm LLM chat-completion clients (OpenAI, Anthropic,
|
|
19
|
+
Groq, Mistral, Gemini, Ollama)
|
|
20
|
+
zerda.vector_database Vector store backends (Chroma, FAISS, Pinecone)
|
|
21
|
+
zerda.document_loaders Loaders for PDF, DOCX, HTML, CSV/Excel, JSON, text
|
|
22
|
+
zerda.chunks Chunking & text-splitting strategies
|
|
23
|
+
zerda.context Query analysis, retrieval fusion, context building
|
|
24
|
+
zerda.cache Multi-level semantic caching
|
|
25
|
+
zerda.memory Conversation / long-term memory management
|
|
26
|
+
zerda.prompt Prompt construction & templating
|
|
27
|
+
zerda.output_parser Structured output parsing & validation
|
|
28
|
+
zerda.router Intent routing & handler dispatch
|
|
29
|
+
zerda.observability Tracing & metrics exporters
|
|
30
|
+
zerda.plugins Plugin system for extending zerda
|
|
31
|
+
|
|
32
|
+
Most third-party integrations (OpenAI, Anthropic, FAISS, Chroma, ...) are
|
|
33
|
+
optional and imported lazily, so installing the base ``zerda`` package
|
|
34
|
+
never forces heavy dependencies onto users who don't need them. Install
|
|
35
|
+
the extras you need, e.g.::
|
|
36
|
+
|
|
37
|
+
pip install "zerda[openai,faiss]"
|
|
38
|
+
pip install "zerda[all]"
|
|
39
|
+
|
|
40
|
+
This top-level module intentionally does **not** eagerly import every
|
|
41
|
+
sub-package: submodules that depend on optional third-party libraries are
|
|
42
|
+
left for the caller to import explicitly (``from zerda.llm import
|
|
43
|
+
OpenAIClient``, etc.) so that a bare ``import zerda`` never fails due to a
|
|
44
|
+
missing optional dependency.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
from __future__ import annotations
|
|
48
|
+
|
|
49
|
+
__title__ = "zerda"
|
|
50
|
+
__description__ = (
|
|
51
|
+
"Advanced Retrieval-Augmented Generation (RAG) toolkit with first-class "
|
|
52
|
+
"Arabic language support. For Arabic Communities, Multilingual LLM Apps, and RAG Systems."
|
|
53
|
+
)
|
|
54
|
+
__version__ = "0.1.0"
|
|
55
|
+
__author__ = "Zerda Contributors"
|
|
56
|
+
__license__ = "MIT"
|
|
57
|
+
|
|
58
|
+
__all__ = [
|
|
59
|
+
"__title__",
|
|
60
|
+
"__description__",
|
|
61
|
+
"__version__",
|
|
62
|
+
"__author__",
|
|
63
|
+
"__license__",
|
|
64
|
+
]
|
zerda/cache/__init__.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from .multi_level_cache import MultiLevelCache
|
|
2
|
+
from .cache_strategies import CacheStrategy
|
|
3
|
+
from .config_cache import CacheConfig,SemanticConfig,SQLiteConfig,SecurityConfig,StorageBackend,RoutingDecision,CostConfig , RedisConfig , PerformanceConfig
|
|
4
|
+
from .cache_entry import CacheEntry
|
|
5
|
+
from .cache_metrics import CacheMetrics
|
|
6
|
+
from .embedding_index import EmbeddingIndex, EmbeddingProvider,OllamaEmbeddingProvider,OpenAIEmbeddingProvider,HuggingFaceEmbeddingProvider,EmbeddingConfig
|
|
7
|
+
from .metrics import CacheMetricsCollector,RollingCounter
|
|
8
|
+
from .models import IntelligentCacheEntry,TenantQuotaState
|
|
9
|
+
from .normalization import QueryNormalizer,NormalizationConfig
|
|
10
|
+
from .policy_learner import CachePolicyLearner,RLConfig,FeedbackSignal
|
|
11
|
+
from .security import SecurityGuard,SecurityViolation
|
|
12
|
+
from .tenant_manager import TenantManager,TenantConfig,TenantRegistration , QuotaExceeded
|
|
13
|
+
from .cache_manager import CacheManager,CacheLookupResult,CachedEmbedder
|
|
14
|
+
from .storage import RedisStorage,SQLiteStorage,MemoryStorage,build_storage
|
|
15
|
+
from .cost_model import CostModel,DecisionEngine,OperationCostEstimate
|
|
16
|
+
|
|
17
|
+
__all__=["CacheEntry","CacheStrategy","MultiLevelCache","CacheMetrics","CacheConfig",
|
|
18
|
+
"EmbeddingIndex","EmbeddingProvider","OllamaEmbeddingProvider","OpenAIEmbeddingProvider","HuggingFaceEmbeddingProvider","EmbeddingConfig",
|
|
19
|
+
"CostModel","CacheMetricsCollector","RollingCounter",
|
|
20
|
+
"IntelligentCacheEntry","TenantQuotaState",
|
|
21
|
+
"QueryNormalizer","NormalizationConfig",
|
|
22
|
+
"CachePolicyLearner",
|
|
23
|
+
"SecurityGuard","SecurityViolation","SecurityConfig","CostConfig",
|
|
24
|
+
"TenantManager","TenantConfig","TenantQuotaState","TenantRegistration",
|
|
25
|
+
"CacheManager","CacheLookupResult","CachedEmbedder",
|
|
26
|
+
"RedisStorage","SQLiteStorage","MemoryStorage","build_storage","RLConfig",
|
|
27
|
+
"SemanticConfig","SQLiteConfig","SecurityConfig","StorageBackend","FeedbackSignal","RoutingDecision","RedisConfig","PerformanceConfig",
|
|
28
|
+
|
|
29
|
+
"DecisionEngine","OperationCostEstimate","QuotaExceeded"
|
|
30
|
+
]
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
import time
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
import pickle
|
|
5
|
+
from .config_cache import CacheConfig
|
|
6
|
+
config=CacheConfig()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class CacheEntry:
|
|
11
|
+
"""
|
|
12
|
+
Represents a cached item with metadata
|
|
13
|
+
"""
|
|
14
|
+
key: str
|
|
15
|
+
value: Any
|
|
16
|
+
created_at: float = field(default_factory=time.time)
|
|
17
|
+
last_access: float = field(default_factory=time.time)
|
|
18
|
+
hits: int = 0
|
|
19
|
+
ttl: Optional[float] = None
|
|
20
|
+
size_bytes: int = 0
|
|
21
|
+
|
|
22
|
+
def __post_init__(self):
|
|
23
|
+
"""
|
|
24
|
+
Calculate size after initialization
|
|
25
|
+
"""
|
|
26
|
+
if self.size_bytes == 0:
|
|
27
|
+
self.size_bytes = self._calculate_size()
|
|
28
|
+
|
|
29
|
+
def _calculate_size(self) -> int:
|
|
30
|
+
"""
|
|
31
|
+
Estimate memory size of cached value
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
try:
|
|
35
|
+
# Try to calculate actual size
|
|
36
|
+
return len(pickle.dumps(self.value))
|
|
37
|
+
except Exception:
|
|
38
|
+
# Default size if calculation fails
|
|
39
|
+
return config.size_bytes # Default 1KB
|
|
40
|
+
|
|
41
|
+
def increment_hits(self) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Increment hit counter and update access time
|
|
44
|
+
"""
|
|
45
|
+
self.hits += 1
|
|
46
|
+
self.last_access = time.time()
|
|
47
|
+
|
|
48
|
+
def is_expired(self) -> bool:
|
|
49
|
+
"""
|
|
50
|
+
Check if entry has expired based on TTL
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
True if expired
|
|
54
|
+
"""
|
|
55
|
+
if self.ttl is None:
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
# Calculate expiration time
|
|
59
|
+
expiration_time = self.created_at + self.ttl
|
|
60
|
+
return time.time() > expiration_time
|
|
61
|
+
|
|
62
|
+
def age(self) -> float:
|
|
63
|
+
"""
|
|
64
|
+
Get age of entry in seconds
|
|
65
|
+
Returns:
|
|
66
|
+
Age in seconds
|
|
67
|
+
"""
|
|
68
|
+
return time.time() - self.created_at
|
|
69
|
+
|
|
70
|
+
def idle_time(self) -> float:
|
|
71
|
+
"""
|
|
72
|
+
Get time since last access in seconds
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Idle time in seconds
|
|
76
|
+
"""
|
|
77
|
+
return time.time() - self.last_access
|
|
78
|
+
|
|
79
|
+
def get_stats(self) -> dict:
|
|
80
|
+
"""
|
|
81
|
+
Get entry statistics
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Statistics dictionary
|
|
85
|
+
"""
|
|
86
|
+
return {
|
|
87
|
+
'key': self.key,
|
|
88
|
+
'hits': self.hits,
|
|
89
|
+
'age_seconds': self.age(),
|
|
90
|
+
'idle_seconds': self.idle_time(),
|
|
91
|
+
'size_bytes': self.size_bytes,
|
|
92
|
+
'is_expired': self.is_expired(),
|
|
93
|
+
'ttl': self.ttl
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
def __repr__(self) -> str:
|
|
97
|
+
"""
|
|
98
|
+
Text representation of entry
|
|
99
|
+
"""
|
|
100
|
+
status = "expired" if self.is_expired() else "valid"
|
|
101
|
+
return (f"CacheEntry(key='{self.key}', hits={self.hits}, "
|
|
102
|
+
f"age={self.age():.1f}s, status={status})")
|