exonware-xwsystem 0.0.1.409__py3-none-any.whl → 0.0.1.411__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.
- exonware/__init__.py +2 -2
- exonware/conf.py +10 -20
- exonware/xwsystem/__init__.py +6 -16
- exonware/xwsystem/caching/__init__.py +1 -1
- exonware/xwsystem/caching/base.py +16 -16
- exonware/xwsystem/caching/bloom_cache.py +5 -5
- exonware/xwsystem/caching/cache_manager.py +2 -2
- exonware/xwsystem/caching/conditional.py +4 -4
- exonware/xwsystem/caching/contracts.py +12 -12
- exonware/xwsystem/caching/decorators.py +2 -2
- exonware/xwsystem/caching/defs.py +1 -1
- exonware/xwsystem/caching/disk_cache.py +4 -4
- exonware/xwsystem/caching/distributed.py +1 -1
- exonware/xwsystem/caching/errors.py +1 -1
- exonware/xwsystem/caching/events.py +8 -8
- exonware/xwsystem/caching/eviction_strategies.py +9 -9
- exonware/xwsystem/caching/fluent.py +1 -1
- exonware/xwsystem/caching/integrity.py +1 -1
- exonware/xwsystem/caching/lfu_cache.py +24 -9
- exonware/xwsystem/caching/lfu_optimized.py +21 -21
- exonware/xwsystem/caching/lru_cache.py +14 -7
- exonware/xwsystem/caching/memory_bounded.py +8 -8
- exonware/xwsystem/caching/metrics_exporter.py +6 -6
- exonware/xwsystem/caching/observable_cache.py +1 -1
- exonware/xwsystem/caching/pluggable_cache.py +9 -9
- exonware/xwsystem/caching/rate_limiter.py +1 -1
- exonware/xwsystem/caching/read_through.py +6 -6
- exonware/xwsystem/caching/secure_cache.py +1 -1
- exonware/xwsystem/caching/serializable.py +3 -3
- exonware/xwsystem/caching/stats.py +7 -7
- exonware/xwsystem/caching/tagging.py +11 -11
- exonware/xwsystem/caching/ttl_cache.py +21 -6
- exonware/xwsystem/caching/two_tier_cache.py +5 -5
- exonware/xwsystem/caching/utils.py +3 -3
- exonware/xwsystem/caching/validation.py +1 -1
- exonware/xwsystem/caching/warming.py +9 -9
- exonware/xwsystem/caching/write_behind.py +5 -5
- exonware/xwsystem/cli/__init__.py +1 -1
- exonware/xwsystem/cli/args.py +10 -10
- exonware/xwsystem/cli/base.py +15 -15
- exonware/xwsystem/cli/colors.py +1 -1
- exonware/xwsystem/cli/console.py +1 -1
- exonware/xwsystem/cli/contracts.py +5 -5
- exonware/xwsystem/cli/defs.py +1 -1
- exonware/xwsystem/cli/errors.py +1 -1
- exonware/xwsystem/cli/progress.py +1 -1
- exonware/xwsystem/cli/prompts.py +1 -1
- exonware/xwsystem/cli/tables.py +7 -7
- exonware/xwsystem/config/__init__.py +1 -1
- exonware/xwsystem/config/base.py +14 -14
- exonware/xwsystem/config/contracts.py +22 -22
- exonware/xwsystem/config/defaults.py +2 -2
- exonware/xwsystem/config/defs.py +1 -1
- exonware/xwsystem/config/errors.py +2 -2
- exonware/xwsystem/config/logging.py +1 -1
- exonware/xwsystem/config/logging_setup.py +2 -2
- exonware/xwsystem/config/performance.py +7 -7
- exonware/xwsystem/config/performance_modes.py +20 -20
- exonware/xwsystem/config/version_manager.py +4 -4
- exonware/xwsystem/{http → http_client}/__init__.py +1 -1
- exonware/xwsystem/{http → http_client}/advanced_client.py +20 -20
- exonware/xwsystem/{http → http_client}/base.py +13 -13
- exonware/xwsystem/{http → http_client}/client.py +43 -43
- exonware/xwsystem/{http → http_client}/contracts.py +5 -5
- exonware/xwsystem/{http → http_client}/defs.py +2 -2
- exonware/xwsystem/{http → http_client}/errors.py +2 -2
- exonware/xwsystem/io/__init__.py +1 -1
- exonware/xwsystem/io/archive/__init__.py +1 -1
- exonware/xwsystem/io/archive/archive.py +5 -5
- exonware/xwsystem/io/archive/archive_files.py +8 -8
- exonware/xwsystem/io/archive/archivers.py +3 -3
- exonware/xwsystem/io/archive/base.py +17 -17
- exonware/xwsystem/io/archive/codec_integration.py +1 -1
- exonware/xwsystem/io/archive/compression.py +1 -1
- exonware/xwsystem/io/archive/formats/__init__.py +1 -1
- exonware/xwsystem/io/archive/formats/brotli_format.py +12 -9
- exonware/xwsystem/io/archive/formats/lz4_format.py +12 -9
- exonware/xwsystem/io/archive/formats/rar.py +12 -9
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -9
- exonware/xwsystem/io/archive/formats/squashfs_format.py +7 -7
- exonware/xwsystem/io/archive/formats/tar.py +8 -8
- exonware/xwsystem/io/archive/formats/wim_format.py +12 -9
- exonware/xwsystem/io/archive/formats/zip.py +8 -8
- exonware/xwsystem/io/archive/formats/zpaq_format.py +7 -7
- exonware/xwsystem/io/archive/formats/zstandard.py +12 -9
- exonware/xwsystem/io/base.py +17 -17
- exonware/xwsystem/io/codec/__init__.py +1 -1
- exonware/xwsystem/io/codec/base.py +261 -14
- exonware/xwsystem/io/codec/contracts.py +3 -6
- exonware/xwsystem/io/codec/registry.py +29 -29
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +2 -2
- exonware/xwsystem/io/common/base.py +1 -1
- exonware/xwsystem/io/common/lock.py +1 -1
- exonware/xwsystem/io/common/watcher.py +4 -4
- exonware/xwsystem/io/contracts.py +34 -39
- exonware/xwsystem/io/data_operations.py +480 -0
- exonware/xwsystem/io/defs.py +2 -2
- exonware/xwsystem/io/errors.py +32 -3
- exonware/xwsystem/io/facade.py +4 -4
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +2 -2
- exonware/xwsystem/io/file/conversion.py +1 -1
- exonware/xwsystem/io/file/file.py +10 -8
- exonware/xwsystem/io/file/paged_source.py +8 -1
- exonware/xwsystem/io/file/paging/__init__.py +1 -1
- exonware/xwsystem/io/file/paging/byte_paging.py +1 -1
- exonware/xwsystem/io/file/paging/line_paging.py +1 -1
- exonware/xwsystem/io/file/paging/record_paging.py +1 -1
- exonware/xwsystem/io/file/paging/registry.py +5 -5
- exonware/xwsystem/io/file/source.py +22 -11
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -1
- exonware/xwsystem/io/filesystem/local.py +9 -1
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +2 -2
- exonware/xwsystem/io/folder/folder.py +6 -6
- exonware/xwsystem/io/serialization/__init__.py +1 -1
- exonware/xwsystem/io/serialization/auto_serializer.py +53 -40
- exonware/xwsystem/io/serialization/base.py +248 -35
- exonware/xwsystem/io/serialization/contracts.py +93 -4
- exonware/xwsystem/io/serialization/defs.py +1 -1
- exonware/xwsystem/io/serialization/errors.py +1 -1
- exonware/xwsystem/io/serialization/flyweight.py +22 -22
- exonware/xwsystem/io/serialization/format_detector.py +18 -15
- exonware/xwsystem/io/serialization/formats/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/bson.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +1 -1
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +1 -1
- exonware/xwsystem/io/serialization/formats/database/dbm.py +53 -1
- exonware/xwsystem/io/serialization/formats/database/shelve.py +48 -1
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +85 -1
- exonware/xwsystem/io/serialization/formats/text/configparser.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/csv.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/formdata.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/json.py +23 -5
- exonware/xwsystem/io/serialization/formats/text/json5.py +98 -13
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +230 -20
- exonware/xwsystem/io/serialization/formats/text/multipart.py +2 -2
- exonware/xwsystem/io/serialization/formats/text/toml.py +65 -4
- exonware/xwsystem/io/serialization/formats/text/xml.py +451 -69
- exonware/xwsystem/io/serialization/formats/text/yaml.py +52 -2
- exonware/xwsystem/io/serialization/registry.py +5 -5
- exonware/xwsystem/io/serialization/serializer.py +184 -12
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -1
- exonware/xwsystem/io/serialization/utils/path_ops.py +3 -3
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +3 -3
- exonware/xwsystem/io/stream/base.py +3 -7
- exonware/xwsystem/io/stream/codec_io.py +4 -7
- exonware/xwsystem/ipc/async_fabric.py +7 -8
- exonware/xwsystem/ipc/base.py +9 -9
- exonware/xwsystem/ipc/contracts.py +5 -5
- exonware/xwsystem/ipc/defs.py +1 -1
- exonware/xwsystem/ipc/errors.py +2 -2
- exonware/xwsystem/ipc/message_queue.py +4 -6
- exonware/xwsystem/ipc/pipes.py +2 -2
- exonware/xwsystem/ipc/process_manager.py +7 -7
- exonware/xwsystem/ipc/process_pool.py +8 -8
- exonware/xwsystem/ipc/shared_memory.py +7 -7
- exonware/xwsystem/monitoring/base.py +33 -33
- exonware/xwsystem/monitoring/contracts.py +27 -27
- exonware/xwsystem/monitoring/defs.py +1 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -16
- exonware/xwsystem/monitoring/errors.py +2 -2
- exonware/xwsystem/monitoring/memory_monitor.py +12 -12
- exonware/xwsystem/monitoring/metrics.py +8 -8
- exonware/xwsystem/monitoring/performance_manager_generic.py +20 -20
- exonware/xwsystem/monitoring/performance_monitor.py +11 -11
- exonware/xwsystem/monitoring/performance_validator.py +21 -21
- exonware/xwsystem/monitoring/system_monitor.py +17 -17
- exonware/xwsystem/monitoring/tracing.py +20 -20
- exonware/xwsystem/monitoring/tracker.py +7 -7
- exonware/xwsystem/operations/__init__.py +5 -5
- exonware/xwsystem/operations/base.py +3 -3
- exonware/xwsystem/operations/contracts.py +3 -3
- exonware/xwsystem/operations/defs.py +5 -5
- exonware/xwsystem/operations/diff.py +5 -5
- exonware/xwsystem/operations/merge.py +2 -2
- exonware/xwsystem/operations/patch.py +5 -5
- exonware/xwsystem/patterns/base.py +4 -4
- exonware/xwsystem/patterns/context_manager.py +7 -7
- exonware/xwsystem/patterns/contracts.py +29 -31
- exonware/xwsystem/patterns/defs.py +1 -1
- exonware/xwsystem/patterns/dynamic_facade.py +9 -9
- exonware/xwsystem/patterns/errors.py +10 -10
- exonware/xwsystem/patterns/handler_factory.py +15 -14
- exonware/xwsystem/patterns/import_registry.py +22 -22
- exonware/xwsystem/patterns/object_pool.py +14 -13
- exonware/xwsystem/patterns/registry.py +45 -32
- exonware/xwsystem/plugins/__init__.py +1 -1
- exonware/xwsystem/plugins/base.py +25 -25
- exonware/xwsystem/plugins/contracts.py +28 -28
- exonware/xwsystem/plugins/defs.py +1 -1
- exonware/xwsystem/plugins/errors.py +9 -9
- exonware/xwsystem/runtime/__init__.py +1 -1
- exonware/xwsystem/runtime/base.py +42 -42
- exonware/xwsystem/runtime/contracts.py +9 -9
- exonware/xwsystem/runtime/defs.py +1 -1
- exonware/xwsystem/runtime/env.py +9 -9
- exonware/xwsystem/runtime/errors.py +1 -1
- exonware/xwsystem/runtime/reflection.py +15 -15
- exonware/xwsystem/security/auth.py +47 -15
- exonware/xwsystem/security/base.py +17 -17
- exonware/xwsystem/security/contracts.py +30 -30
- exonware/xwsystem/security/crypto.py +8 -8
- exonware/xwsystem/security/defs.py +1 -1
- exonware/xwsystem/security/errors.py +2 -2
- exonware/xwsystem/security/hazmat.py +7 -7
- exonware/xwsystem/security/path_validator.py +1 -1
- exonware/xwsystem/shared/__init__.py +1 -1
- exonware/xwsystem/shared/base.py +14 -14
- exonware/xwsystem/shared/contracts.py +6 -6
- exonware/xwsystem/shared/defs.py +1 -1
- exonware/xwsystem/shared/errors.py +1 -1
- exonware/xwsystem/structures/__init__.py +1 -1
- exonware/xwsystem/structures/base.py +29 -29
- exonware/xwsystem/structures/circular_detector.py +15 -15
- exonware/xwsystem/structures/contracts.py +9 -9
- exonware/xwsystem/structures/defs.py +1 -1
- exonware/xwsystem/structures/errors.py +2 -2
- exonware/xwsystem/structures/tree_walker.py +8 -8
- exonware/xwsystem/threading/async_primitives.py +7 -7
- exonware/xwsystem/threading/base.py +19 -19
- exonware/xwsystem/threading/contracts.py +13 -13
- exonware/xwsystem/threading/defs.py +1 -1
- exonware/xwsystem/threading/errors.py +2 -2
- exonware/xwsystem/threading/safe_factory.py +13 -12
- exonware/xwsystem/utils/base.py +34 -34
- exonware/xwsystem/utils/contracts.py +9 -9
- exonware/xwsystem/utils/dt/__init__.py +1 -1
- exonware/xwsystem/utils/dt/base.py +6 -6
- exonware/xwsystem/utils/dt/contracts.py +2 -2
- exonware/xwsystem/utils/dt/defs.py +1 -1
- exonware/xwsystem/utils/dt/errors.py +2 -2
- exonware/xwsystem/utils/dt/formatting.py +3 -3
- exonware/xwsystem/utils/dt/humanize.py +2 -2
- exonware/xwsystem/utils/dt/parsing.py +2 -2
- exonware/xwsystem/utils/dt/timezone_utils.py +5 -5
- exonware/xwsystem/utils/errors.py +2 -2
- exonware/xwsystem/utils/test_runner.py +6 -6
- exonware/xwsystem/utils/utils_contracts.py +1 -1
- exonware/xwsystem/validation/__init__.py +1 -1
- exonware/xwsystem/validation/base.py +48 -48
- exonware/xwsystem/validation/contracts.py +8 -8
- exonware/xwsystem/validation/data_validator.py +10 -0
- exonware/xwsystem/validation/declarative.py +15 -15
- exonware/xwsystem/validation/defs.py +1 -1
- exonware/xwsystem/validation/errors.py +2 -2
- exonware/xwsystem/validation/fluent_validator.py +10 -10
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/METADATA +9 -11
- exonware_xwsystem-0.0.1.411.dist-info/RECORD +274 -0
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/WHEEL +1 -1
- exonware/xwsystem/lazy_bootstrap.py +0 -79
- exonware_xwsystem-0.0.1.409.dist-info/RECORD +0 -274
- {exonware_xwsystem-0.0.1.409.dist-info → exonware_xwsystem-0.0.1.411.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
Company: eXonware.com
|
|
4
4
|
Author: Eng. Muhammad AlShehri
|
|
5
5
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.0.1.
|
|
6
|
+
Version: 0.0.1.411
|
|
7
7
|
Generation Date: 01-Nov-2025
|
|
8
8
|
|
|
9
9
|
Tag-based cache invalidation.
|
|
10
10
|
Extensibility Priority #5 - Flexible invalidation patterns.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from typing import Any,
|
|
13
|
+
from typing import Any, Optional, Hashable
|
|
14
14
|
from collections import defaultdict
|
|
15
15
|
from .lru_cache import LRUCache
|
|
16
16
|
from ..config.logging_setup import get_logger
|
|
17
17
|
|
|
18
|
-
logger = get_logger("
|
|
18
|
+
logger = get_logger("xwsystem.caching.tagging")
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class TaggedCache(LRUCache):
|
|
@@ -51,11 +51,11 @@ class TaggedCache(LRUCache):
|
|
|
51
51
|
super().__init__(capacity, ttl, name)
|
|
52
52
|
|
|
53
53
|
# Tag tracking
|
|
54
|
-
self._key_to_tags:
|
|
55
|
-
self._tag_to_keys:
|
|
54
|
+
self._key_to_tags: dict[Hashable, set[str]] = {}
|
|
55
|
+
self._tag_to_keys: dict[str, set[Hashable]] = defaultdict(set)
|
|
56
56
|
self._invalidations = 0
|
|
57
57
|
|
|
58
|
-
def put(self, key: Hashable, value: Any, tags: Optional[
|
|
58
|
+
def put(self, key: Hashable, value: Any, tags: Optional[list[str]] = None) -> None:
|
|
59
59
|
"""
|
|
60
60
|
Put value with optional tags.
|
|
61
61
|
|
|
@@ -123,7 +123,7 @@ class TaggedCache(LRUCache):
|
|
|
123
123
|
logger.info(f"Invalidated {count} entries with tag '{tag}'")
|
|
124
124
|
return count
|
|
125
125
|
|
|
126
|
-
def invalidate_by_tags(self, tags:
|
|
126
|
+
def invalidate_by_tags(self, tags: list[str]) -> int:
|
|
127
127
|
"""
|
|
128
128
|
Invalidate all entries with any of the specified tags.
|
|
129
129
|
|
|
@@ -148,7 +148,7 @@ class TaggedCache(LRUCache):
|
|
|
148
148
|
logger.info(f"Invalidated {count} entries with tags: {tags}")
|
|
149
149
|
return count
|
|
150
150
|
|
|
151
|
-
def get_keys_by_tag(self, tag: str) ->
|
|
151
|
+
def get_keys_by_tag(self, tag: str) -> set[Hashable]:
|
|
152
152
|
"""
|
|
153
153
|
Get all keys associated with a tag.
|
|
154
154
|
|
|
@@ -160,7 +160,7 @@ class TaggedCache(LRUCache):
|
|
|
160
160
|
"""
|
|
161
161
|
return self._tag_to_keys.get(tag, set()).copy()
|
|
162
162
|
|
|
163
|
-
def get_tags(self, key: Hashable) ->
|
|
163
|
+
def get_tags(self, key: Hashable) -> set[str]:
|
|
164
164
|
"""
|
|
165
165
|
Get all tags associated with a key.
|
|
166
166
|
|
|
@@ -172,7 +172,7 @@ class TaggedCache(LRUCache):
|
|
|
172
172
|
"""
|
|
173
173
|
return self._key_to_tags.get(key, set()).copy()
|
|
174
174
|
|
|
175
|
-
def get_all_tags(self) ->
|
|
175
|
+
def get_all_tags(self) -> set[str]:
|
|
176
176
|
"""
|
|
177
177
|
Get all tags in cache.
|
|
178
178
|
|
|
@@ -187,7 +187,7 @@ class TaggedCache(LRUCache):
|
|
|
187
187
|
self._key_to_tags.clear()
|
|
188
188
|
self._tag_to_keys.clear()
|
|
189
189
|
|
|
190
|
-
def get_stats(self) ->
|
|
190
|
+
def get_stats(self) -> dict[str, Any]:
|
|
191
191
|
"""Get statistics including tag information."""
|
|
192
192
|
stats = super().get_stats()
|
|
193
193
|
stats['total_tags'] = len(self._tag_to_keys)
|
|
@@ -7,14 +7,14 @@ Production-grade TTL caching for XSystem.
|
|
|
7
7
|
Company: eXonware.com
|
|
8
8
|
Author: Eng. Muhammad AlShehri
|
|
9
9
|
Email: connect@exonware.com
|
|
10
|
-
Version: 0.0.1.
|
|
10
|
+
Version: 0.0.1.411
|
|
11
11
|
Generated: 2025-01-27
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
import asyncio
|
|
15
15
|
import time
|
|
16
16
|
import threading
|
|
17
|
-
from typing import Any,
|
|
17
|
+
from typing import Any, Optional, Union
|
|
18
18
|
from dataclasses import dataclass
|
|
19
19
|
import logging
|
|
20
20
|
from .base import ACache
|
|
@@ -83,7 +83,7 @@ class TTLCache(ACache):
|
|
|
83
83
|
self.name = name
|
|
84
84
|
|
|
85
85
|
# Storage
|
|
86
|
-
self._cache:
|
|
86
|
+
self._cache: dict[str, TTLEntry] = {}
|
|
87
87
|
self._access_order = [] # For LRU tracking
|
|
88
88
|
|
|
89
89
|
# Thread safety
|
|
@@ -298,7 +298,22 @@ class TTLCache(ACache):
|
|
|
298
298
|
|
|
299
299
|
return True
|
|
300
300
|
|
|
301
|
-
def
|
|
301
|
+
def keys(self) -> list[str]:
|
|
302
|
+
"""Get list of all cache keys."""
|
|
303
|
+
with self._lock:
|
|
304
|
+
return list(self._cache.keys())
|
|
305
|
+
|
|
306
|
+
def values(self) -> list[Any]:
|
|
307
|
+
"""Get list of all cache values."""
|
|
308
|
+
with self._lock:
|
|
309
|
+
return [entry.value for entry in self._cache.values() if not entry.is_expired()]
|
|
310
|
+
|
|
311
|
+
def items(self) -> list[tuple[str, Any]]:
|
|
312
|
+
"""Get list of all key-value pairs."""
|
|
313
|
+
with self._lock:
|
|
314
|
+
return [(key, entry.value) for key, entry in self._cache.items() if not entry.is_expired()]
|
|
315
|
+
|
|
316
|
+
def get_stats(self) -> dict[str, Any]:
|
|
302
317
|
"""Get cache statistics."""
|
|
303
318
|
with self._lock:
|
|
304
319
|
total_requests = self._stats['hits'] + self._stats['misses']
|
|
@@ -369,7 +384,7 @@ class AsyncTTLCache:
|
|
|
369
384
|
self.name = name
|
|
370
385
|
|
|
371
386
|
# Storage
|
|
372
|
-
self._cache:
|
|
387
|
+
self._cache: dict[str, TTLEntry] = {}
|
|
373
388
|
self._access_order = []
|
|
374
389
|
|
|
375
390
|
# Async synchronization
|
|
@@ -497,7 +512,7 @@ class AsyncTTLCache:
|
|
|
497
512
|
async with self._lock:
|
|
498
513
|
return len(self._cache)
|
|
499
514
|
|
|
500
|
-
async def get_stats(self) ->
|
|
515
|
+
async def get_stats(self) -> dict[str, Any]:
|
|
501
516
|
"""Get async cache statistics."""
|
|
502
517
|
async with self._lock:
|
|
503
518
|
total_requests = self._stats['hits'] + self._stats['misses']
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
Company: eXonware.com
|
|
4
4
|
Author: Eng. Muhammad AlShehri
|
|
5
5
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.0.1.
|
|
6
|
+
Version: 0.0.1.411
|
|
7
7
|
Generation Date: October 26, 2025
|
|
8
8
|
|
|
9
9
|
Two-tier cache implementation combining memory and disk caching.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import threading
|
|
13
|
-
from typing import Any, Optional
|
|
13
|
+
from typing import Any, Optional
|
|
14
14
|
from .lru_cache import LRUCache
|
|
15
15
|
from .disk_cache import DiskCache
|
|
16
16
|
from .contracts import ICache
|
|
@@ -169,7 +169,7 @@ class TwoTierCache(ICache):
|
|
|
169
169
|
with self._lock:
|
|
170
170
|
return self.memory_cache.size() + self.disk_cache.size()
|
|
171
171
|
|
|
172
|
-
def get_stats(self) ->
|
|
172
|
+
def get_stats(self) -> dict[str, Any]:
|
|
173
173
|
"""Get comprehensive statistics for both tiers."""
|
|
174
174
|
with self._lock:
|
|
175
175
|
memory_stats = self.memory_cache.get_stats()
|
|
@@ -197,11 +197,11 @@ class TwoTierCache(ICache):
|
|
|
197
197
|
'disk_stats': disk_stats,
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
def get_memory_stats(self) ->
|
|
200
|
+
def get_memory_stats(self) -> dict[str, Any]:
|
|
201
201
|
"""Get memory tier statistics."""
|
|
202
202
|
return self.memory_cache.get_stats()
|
|
203
203
|
|
|
204
|
-
def get_disk_stats(self) ->
|
|
204
|
+
def get_disk_stats(self) -> dict[str, Any]:
|
|
205
205
|
"""Get disk tier statistics."""
|
|
206
206
|
return self.disk_cache.get_stats()
|
|
207
207
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.0.1.
|
|
7
|
+
Version: 0.0.1.411
|
|
8
8
|
Generation Date: 01-Nov-2025
|
|
9
9
|
|
|
10
10
|
Common utility functions for caching module.
|
|
@@ -13,7 +13,7 @@ Common utility functions for caching module.
|
|
|
13
13
|
import sys
|
|
14
14
|
import hashlib
|
|
15
15
|
import pickle
|
|
16
|
-
from typing import Any, Callable
|
|
16
|
+
from typing import Any, Callable
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def estimate_object_size(obj: Any) -> int:
|
|
@@ -110,7 +110,7 @@ def format_bytes(size: int) -> str:
|
|
|
110
110
|
return f"{size_float:.2f} {units[unit_index]}"
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
def default_key_builder(func: Callable, args:
|
|
113
|
+
def default_key_builder(func: Callable, args: tuple, kwargs: dict) -> str:
|
|
114
114
|
"""
|
|
115
115
|
Build cache key from function and arguments.
|
|
116
116
|
|
|
@@ -4,26 +4,26 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.0.1.
|
|
7
|
+
Version: 0.0.1.411
|
|
8
8
|
Generation Date: 01-Nov-2025
|
|
9
9
|
|
|
10
10
|
Cache warming utilities for preloading data.
|
|
11
11
|
Performance Priority #4 - Reduce cold start penalties.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
from typing import Any, Callable,
|
|
14
|
+
from typing import Any, Callable, Optional, Hashable
|
|
15
15
|
from abc import ABC, abstractmethod
|
|
16
16
|
import time
|
|
17
17
|
from ..config.logging_setup import get_logger
|
|
18
18
|
|
|
19
|
-
logger = get_logger("
|
|
19
|
+
logger = get_logger("xwsystem.caching.warming")
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class AWarmingStrategy(ABC):
|
|
23
23
|
"""Abstract base class for cache warming strategies."""
|
|
24
24
|
|
|
25
25
|
@abstractmethod
|
|
26
|
-
def warm(self, cache: Any, keys:
|
|
26
|
+
def warm(self, cache: Any, keys: list[Hashable], loader: Callable[[Hashable], Any]) -> int:
|
|
27
27
|
"""
|
|
28
28
|
Warm cache with data.
|
|
29
29
|
|
|
@@ -45,7 +45,7 @@ class PreloadWarmingStrategy(AWarmingStrategy):
|
|
|
45
45
|
Suitable for small datasets that fit entirely in cache.
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
|
-
def warm(self, cache: Any, keys:
|
|
48
|
+
def warm(self, cache: Any, keys: list[Hashable], loader: Callable[[Hashable], Any]) -> int:
|
|
49
49
|
"""Preload all keys into cache."""
|
|
50
50
|
success_count = 0
|
|
51
51
|
failures = []
|
|
@@ -91,7 +91,7 @@ class LazyWarmingStrategy(AWarmingStrategy):
|
|
|
91
91
|
"""
|
|
92
92
|
self.preload_limit = preload_limit
|
|
93
93
|
|
|
94
|
-
def warm(self, cache: Any, keys:
|
|
94
|
+
def warm(self, cache: Any, keys: list[Hashable], loader: Callable[[Hashable], Any]) -> int:
|
|
95
95
|
"""Preload limited number of keys, rest loaded lazily."""
|
|
96
96
|
# Preload up to limit
|
|
97
97
|
preload_keys = keys[:self.preload_limit]
|
|
@@ -129,7 +129,7 @@ class PriorityWarmingStrategy(AWarmingStrategy):
|
|
|
129
129
|
"""
|
|
130
130
|
self.priority_func = priority_func
|
|
131
131
|
|
|
132
|
-
def warm(self, cache: Any, keys:
|
|
132
|
+
def warm(self, cache: Any, keys: list[Hashable], loader: Callable[[Hashable], Any]) -> int:
|
|
133
133
|
"""Load keys in priority order."""
|
|
134
134
|
# Sort keys by priority (descending)
|
|
135
135
|
sorted_keys = sorted(keys, key=self.priority_func, reverse=True)
|
|
@@ -151,7 +151,7 @@ class PriorityWarmingStrategy(AWarmingStrategy):
|
|
|
151
151
|
def warm_cache(
|
|
152
152
|
cache: Any,
|
|
153
153
|
loader: Callable[[Hashable], Any],
|
|
154
|
-
keys:
|
|
154
|
+
keys: list[Hashable],
|
|
155
155
|
strategy: Optional[AWarmingStrategy] = None,
|
|
156
156
|
on_progress: Optional[Callable[[int, int], None]] = None
|
|
157
157
|
) -> int:
|
|
@@ -198,7 +198,7 @@ def warm_cache(
|
|
|
198
198
|
def warm_cache_async(
|
|
199
199
|
cache: Any,
|
|
200
200
|
loader: Callable,
|
|
201
|
-
keys:
|
|
201
|
+
keys: list[Hashable]
|
|
202
202
|
) -> int:
|
|
203
203
|
"""
|
|
204
204
|
Warm async cache with data.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Company: eXonware.com
|
|
4
4
|
Author: Eng. Muhammad AlShehri
|
|
5
5
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.0.1.
|
|
6
|
+
Version: 0.0.1.411
|
|
7
7
|
Generation Date: 01-Nov-2025
|
|
8
8
|
|
|
9
9
|
Write-behind (lazy write) cache implementation.
|
|
@@ -12,11 +12,11 @@ Performance Priority #4 - Delayed persistence for better write performance.
|
|
|
12
12
|
|
|
13
13
|
import threading
|
|
14
14
|
import time
|
|
15
|
-
from typing import Any, Callable,
|
|
15
|
+
from typing import Any, Callable, Optional, Hashable
|
|
16
16
|
from .lru_cache import LRUCache
|
|
17
17
|
from ..config.logging_setup import get_logger
|
|
18
18
|
|
|
19
|
-
logger = get_logger("
|
|
19
|
+
logger = get_logger("xwsystem.caching.write_behind")
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class WriteBehindCache(LRUCache):
|
|
@@ -77,7 +77,7 @@ class WriteBehindCache(LRUCache):
|
|
|
77
77
|
self.flush_interval = flush_interval
|
|
78
78
|
|
|
79
79
|
# Dirty entry tracking
|
|
80
|
-
self._dirty_keys:
|
|
80
|
+
self._dirty_keys: set[Hashable] = set()
|
|
81
81
|
self._flush_lock = threading.Lock()
|
|
82
82
|
|
|
83
83
|
# Statistics
|
|
@@ -195,7 +195,7 @@ class WriteBehindCache(LRUCache):
|
|
|
195
195
|
|
|
196
196
|
logger.debug("Background flusher stopped")
|
|
197
197
|
|
|
198
|
-
def get_stats(self) ->
|
|
198
|
+
def get_stats(self) -> dict[str, Any]:
|
|
199
199
|
"""Get statistics including write-behind metrics."""
|
|
200
200
|
stats = super().get_stats()
|
|
201
201
|
stats['dirty_entries'] = len(self._dirty_keys)
|
exonware/xwsystem/cli/args.py
CHANGED
|
@@ -7,13 +7,13 @@ Production-grade CLI argument parsing for XWSystem.
|
|
|
7
7
|
Company: eXonware.com
|
|
8
8
|
Author: Eng. Muhammad AlShehri
|
|
9
9
|
Email: connect@exonware.com
|
|
10
|
-
Version: 0.0.1.
|
|
10
|
+
Version: 0.0.1.411
|
|
11
11
|
Generated: 2025-01-27
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
import argparse
|
|
15
15
|
import sys
|
|
16
|
-
from typing import Any,
|
|
16
|
+
from typing import Any, Optional, Callable, Union
|
|
17
17
|
from dataclasses import dataclass
|
|
18
18
|
import logging
|
|
19
19
|
from .defs import ArgumentType
|
|
@@ -40,7 +40,7 @@ class Argument:
|
|
|
40
40
|
default: Any = None
|
|
41
41
|
help_text: str = ""
|
|
42
42
|
short_name: Optional[str] = None
|
|
43
|
-
choices: Optional[
|
|
43
|
+
choices: Optional[list[str]] = None
|
|
44
44
|
validator: Optional[Callable[[Any], bool]] = None
|
|
45
45
|
action: str = "store" # store, store_true, store_false, append, count
|
|
46
46
|
nargs: Optional[Union[int, str]] = None # Number of arguments
|
|
@@ -72,9 +72,9 @@ class Command:
|
|
|
72
72
|
name: str
|
|
73
73
|
handler: Callable
|
|
74
74
|
description: str = ""
|
|
75
|
-
arguments:
|
|
76
|
-
subcommands:
|
|
77
|
-
examples:
|
|
75
|
+
arguments: list[Argument] = None
|
|
76
|
+
subcommands: list['Command'] = None
|
|
77
|
+
examples: list[str] = None
|
|
78
78
|
|
|
79
79
|
def __post_init__(self):
|
|
80
80
|
"""Initialize command defaults."""
|
|
@@ -134,9 +134,9 @@ class ArgumentParser:
|
|
|
134
134
|
)
|
|
135
135
|
|
|
136
136
|
# Command registry
|
|
137
|
-
self._commands:
|
|
137
|
+
self._commands: dict[str, Command] = {}
|
|
138
138
|
self._subparsers = None
|
|
139
|
-
self._global_arguments:
|
|
139
|
+
self._global_arguments: list[Argument] = []
|
|
140
140
|
|
|
141
141
|
def add_argument(self, argument: Argument) -> 'ArgumentParser':
|
|
142
142
|
"""
|
|
@@ -256,7 +256,7 @@ class ArgumentParser:
|
|
|
256
256
|
|
|
257
257
|
parser.add_argument(*names, **kwargs)
|
|
258
258
|
|
|
259
|
-
def parse_args(self, args:
|
|
259
|
+
def parse_args(self, args: list[str] = None) -> argparse.Namespace:
|
|
260
260
|
"""
|
|
261
261
|
Parse command-line arguments.
|
|
262
262
|
|
|
@@ -282,7 +282,7 @@ class ArgumentParser:
|
|
|
282
282
|
self._parser.print_help()
|
|
283
283
|
sys.exit(1)
|
|
284
284
|
|
|
285
|
-
def execute(self, args:
|
|
285
|
+
def execute(self, args: list[str] = None) -> Any:
|
|
286
286
|
"""
|
|
287
287
|
Parse arguments and execute the appropriate command.
|
|
288
288
|
|
exonware/xwsystem/cli/base.py
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
Company: eXonware.com
|
|
4
4
|
Author: Eng. Muhammad AlShehri
|
|
5
5
|
Email: connect@exonware.com
|
|
6
|
-
Version: 0.0.1.
|
|
6
|
+
Version: 0.0.1.411
|
|
7
7
|
Generation Date: September 04, 2025
|
|
8
8
|
|
|
9
9
|
CLI module base classes - abstract classes for command-line interface functionality.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from abc import ABC, abstractmethod
|
|
13
|
-
from typing import Any,
|
|
13
|
+
from typing import Any, Optional, Union
|
|
14
14
|
from .contracts import ColorType, ProgressStyle, TableStyle, PromptType, ICLI
|
|
15
15
|
from ..version import __version__
|
|
16
16
|
|
|
@@ -85,7 +85,7 @@ class AProgressBarBase(ABC):
|
|
|
85
85
|
class ATableBase(ABC):
|
|
86
86
|
"""Abstract base class for table operations."""
|
|
87
87
|
|
|
88
|
-
def __init__(self, headers:
|
|
88
|
+
def __init__(self, headers: list[str], style: TableStyle = TableStyle.SIMPLE):
|
|
89
89
|
"""
|
|
90
90
|
Initialize table.
|
|
91
91
|
|
|
@@ -95,7 +95,7 @@ class ATableBase(ABC):
|
|
|
95
95
|
"""
|
|
96
96
|
self.headers = headers
|
|
97
97
|
self.style = style
|
|
98
|
-
self.rows:
|
|
98
|
+
self.rows: list[list[str]] = []
|
|
99
99
|
|
|
100
100
|
@abstractmethod
|
|
101
101
|
def add_row(self, *values: Any) -> None:
|
|
@@ -132,12 +132,12 @@ class APromptBase(ABC):
|
|
|
132
132
|
pass
|
|
133
133
|
|
|
134
134
|
@abstractmethod
|
|
135
|
-
def select(self, message: str, choices:
|
|
135
|
+
def select(self, message: str, choices: list[str], default: Optional[str] = None) -> str:
|
|
136
136
|
"""Ask user to select from choices."""
|
|
137
137
|
pass
|
|
138
138
|
|
|
139
139
|
@abstractmethod
|
|
140
|
-
def multiselect(self, message: str, choices:
|
|
140
|
+
def multiselect(self, message: str, choices: list[str], default: Optional[list[str]] = None) -> list[str]:
|
|
141
141
|
"""Ask user to select multiple choices."""
|
|
142
142
|
pass
|
|
143
143
|
|
|
@@ -153,7 +153,7 @@ class AArgumentParserBase(ABC):
|
|
|
153
153
|
description: Parser description
|
|
154
154
|
"""
|
|
155
155
|
self.description = description
|
|
156
|
-
self.arguments:
|
|
156
|
+
self.arguments: list[dict[str, Any]] = []
|
|
157
157
|
|
|
158
158
|
@abstractmethod
|
|
159
159
|
def add_argument(self, *args, **kwargs) -> None:
|
|
@@ -161,7 +161,7 @@ class AArgumentParserBase(ABC):
|
|
|
161
161
|
pass
|
|
162
162
|
|
|
163
163
|
@abstractmethod
|
|
164
|
-
def parse_args(self, args: Optional[
|
|
164
|
+
def parse_args(self, args: Optional[list[str]] = None) -> Any:
|
|
165
165
|
"""Parse command line arguments."""
|
|
166
166
|
pass
|
|
167
167
|
|
|
@@ -190,7 +190,7 @@ class AColorBase(ABC):
|
|
|
190
190
|
pass
|
|
191
191
|
|
|
192
192
|
@abstractmethod
|
|
193
|
-
def get_color_codes(self) ->
|
|
193
|
+
def get_color_codes(self) -> dict[ColorType, str]:
|
|
194
194
|
"""Get color codes mapping."""
|
|
195
195
|
pass
|
|
196
196
|
|
|
@@ -207,8 +207,8 @@ class BaseCLI(ICLI):
|
|
|
207
207
|
"""
|
|
208
208
|
self._name = name
|
|
209
209
|
self._version = version or __version__
|
|
210
|
-
self._commands:
|
|
211
|
-
self._options:
|
|
210
|
+
self._commands: dict[str, Any] = {}
|
|
211
|
+
self._options: dict[str, Any] = {}
|
|
212
212
|
|
|
213
213
|
@property
|
|
214
214
|
def name(self) -> str:
|
|
@@ -238,7 +238,7 @@ class BaseCLI(ICLI):
|
|
|
238
238
|
"""
|
|
239
239
|
self._options[name] = option
|
|
240
240
|
|
|
241
|
-
def run(self, args: Optional[
|
|
241
|
+
def run(self, args: Optional[list[str]] = None) -> int:
|
|
242
242
|
"""Run the CLI.
|
|
243
243
|
|
|
244
244
|
Args:
|
|
@@ -262,8 +262,8 @@ class BaseCLI(ICLI):
|
|
|
262
262
|
"""Initialize base CLI."""
|
|
263
263
|
self._name = name
|
|
264
264
|
self._version = version or __version__
|
|
265
|
-
self._commands:
|
|
266
|
-
self._options:
|
|
265
|
+
self._commands: dict[str, Any] = {}
|
|
266
|
+
self._options: dict[str, Any] = {}
|
|
267
267
|
|
|
268
268
|
@property
|
|
269
269
|
def name(self) -> str:
|
|
@@ -283,7 +283,7 @@ class BaseCLI(ICLI):
|
|
|
283
283
|
"""Add an option to the CLI."""
|
|
284
284
|
self._options[name] = option
|
|
285
285
|
|
|
286
|
-
def run(self, args: Optional[
|
|
286
|
+
def run(self, args: Optional[list[str]] = None) -> int:
|
|
287
287
|
"""Run the CLI."""
|
|
288
288
|
if not args:
|
|
289
289
|
args = []
|
exonware/xwsystem/cli/colors.py
CHANGED
exonware/xwsystem/cli/console.py
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Company: eXonware.com
|
|
3
3
|
Author: Eng. Muhammad AlShehri
|
|
4
4
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.0.1.
|
|
5
|
+
Version: 0.0.1.411
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
CLI module contracts - interfaces and enums for command-line interface functionality.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from abc import ABC, abstractmethod
|
|
12
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, Optional, Union
|
|
13
13
|
|
|
14
14
|
# Import enums from types module
|
|
15
15
|
from .defs import (
|
|
@@ -95,7 +95,7 @@ class IArgumentParser(ABC):
|
|
|
95
95
|
pass
|
|
96
96
|
|
|
97
97
|
@abstractmethod
|
|
98
|
-
def parse_args(self, args: Optional[
|
|
98
|
+
def parse_args(self, args: Optional[list[str]] = None) -> Any:
|
|
99
99
|
"""Parse command line arguments."""
|
|
100
100
|
pass
|
|
101
101
|
|
|
@@ -126,7 +126,7 @@ class ICLI(ABC):
|
|
|
126
126
|
pass
|
|
127
127
|
|
|
128
128
|
@abstractmethod
|
|
129
|
-
def run(self, args: Optional[
|
|
129
|
+
def run(self, args: Optional[list[str]] = None) -> int:
|
|
130
130
|
"""Run the CLI."""
|
|
131
131
|
pass
|
|
132
132
|
|
|
@@ -169,7 +169,7 @@ class IPrompts(ABC):
|
|
|
169
169
|
pass
|
|
170
170
|
|
|
171
171
|
@abstractmethod
|
|
172
|
-
def select(self, message: str, choices:
|
|
172
|
+
def select(self, message: str, choices: list[str], default: Optional[str] = None) -> str:
|
|
173
173
|
"""Ask user to select from choices."""
|
|
174
174
|
pass
|
|
175
175
|
|
exonware/xwsystem/cli/defs.py
CHANGED
exonware/xwsystem/cli/errors.py
CHANGED