exonware-xwsystem 0.0.1.410__py3-none-any.whl → 0.1.0.1__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 +1 -1
- exonware/conf.py +1 -1
- exonware/xwsystem/__init__.py +2 -2
- exonware/xwsystem/caching/__init__.py +1 -1
- exonware/xwsystem/caching/base.py +2 -2
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +1 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +1 -1
- exonware/xwsystem/caching/decorators.py +2 -2
- exonware/xwsystem/caching/defs.py +1 -1
- exonware/xwsystem/caching/disk_cache.py +1 -1
- exonware/xwsystem/caching/distributed.py +1 -1
- exonware/xwsystem/caching/errors.py +1 -1
- exonware/xwsystem/caching/events.py +2 -2
- exonware/xwsystem/caching/eviction_strategies.py +1 -1
- exonware/xwsystem/caching/fluent.py +1 -1
- exonware/xwsystem/caching/integrity.py +1 -1
- exonware/xwsystem/caching/lfu_cache.py +2 -2
- exonware/xwsystem/caching/lfu_optimized.py +3 -3
- exonware/xwsystem/caching/lru_cache.py +2 -2
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +1 -1
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +1 -1
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +1 -1
- exonware/xwsystem/caching/serializable.py +2 -2
- exonware/xwsystem/caching/stats.py +1 -1
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +1 -1
- exonware/xwsystem/caching/two_tier_cache.py +1 -1
- exonware/xwsystem/caching/utils.py +1 -1
- exonware/xwsystem/caching/validation.py +1 -1
- exonware/xwsystem/caching/warming.py +2 -2
- exonware/xwsystem/caching/write_behind.py +2 -2
- exonware/xwsystem/cli/__init__.py +1 -1
- exonware/xwsystem/cli/args.py +1 -1
- exonware/xwsystem/cli/base.py +1 -1
- exonware/xwsystem/cli/colors.py +1 -1
- exonware/xwsystem/cli/console.py +1 -1
- exonware/xwsystem/cli/contracts.py +1 -1
- 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 +1 -1
- exonware/xwsystem/config/__init__.py +1 -1
- exonware/xwsystem/config/base.py +2 -2
- exonware/xwsystem/config/contracts.py +1 -1
- exonware/xwsystem/config/defaults.py +1 -1
- 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 +115 -388
- exonware/xwsystem/http_client/__init__.py +1 -1
- exonware/xwsystem/http_client/advanced_client.py +2 -2
- exonware/xwsystem/http_client/base.py +2 -2
- exonware/xwsystem/http_client/client.py +2 -2
- exonware/xwsystem/http_client/contracts.py +1 -1
- exonware/xwsystem/http_client/defs.py +1 -1
- exonware/xwsystem/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 +1 -1
- exonware/xwsystem/io/archive/archive_files.py +1 -1
- exonware/xwsystem/io/archive/archivers.py +2 -2
- exonware/xwsystem/io/archive/base.py +6 -6
- 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 +6 -3
- exonware/xwsystem/io/archive/formats/lz4_format.py +6 -3
- exonware/xwsystem/io/archive/formats/rar.py +6 -3
- exonware/xwsystem/io/archive/formats/sevenzip.py +6 -3
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -1
- exonware/xwsystem/io/archive/formats/tar.py +1 -1
- exonware/xwsystem/io/archive/formats/wim_format.py +6 -3
- exonware/xwsystem/io/archive/formats/zip.py +1 -1
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -1
- exonware/xwsystem/io/archive/formats/zstandard.py +6 -3
- exonware/xwsystem/io/base.py +1 -1
- exonware/xwsystem/io/codec/__init__.py +1 -1
- exonware/xwsystem/io/codec/base.py +6 -6
- exonware/xwsystem/io/codec/contracts.py +1 -1
- exonware/xwsystem/io/codec/registry.py +5 -5
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/base.py +1 -1
- exonware/xwsystem/io/common/lock.py +1 -1
- exonware/xwsystem/io/common/watcher.py +1 -1
- exonware/xwsystem/io/contracts.py +1 -1
- exonware/xwsystem/io/data_operations.py +746 -0
- exonware/xwsystem/io/defs.py +1 -1
- exonware/xwsystem/io/errors.py +1 -1
- exonware/xwsystem/io/facade.py +2 -2
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +1 -1
- exonware/xwsystem/io/file/conversion.py +1 -1
- exonware/xwsystem/io/file/file.py +8 -6
- 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 +4 -4
- exonware/xwsystem/io/file/source.py +20 -9
- 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 +1 -1
- exonware/xwsystem/io/folder/folder.py +2 -2
- exonware/xwsystem/io/serialization/__init__.py +1 -1
- exonware/xwsystem/io/serialization/auto_serializer.py +52 -39
- exonware/xwsystem/io/serialization/base.py +165 -1
- exonware/xwsystem/io/serialization/contracts.py +88 -1
- exonware/xwsystem/io/serialization/defs.py +1 -1
- exonware/xwsystem/io/serialization/errors.py +1 -1
- exonware/xwsystem/io/serialization/flyweight.py +10 -10
- exonware/xwsystem/io/serialization/format_detector.py +8 -5
- 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/append_only_log.py +201 -0
- exonware/xwsystem/io/serialization/formats/text/configparser.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/csv.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/formdata.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/json.py +43 -20
- exonware/xwsystem/io/serialization/formats/text/json5.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +316 -22
- exonware/xwsystem/io/serialization/formats/text/multipart.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/toml.py +19 -3
- exonware/xwsystem/io/serialization/formats/text/xml.py +8 -1
- exonware/xwsystem/io/serialization/formats/text/yaml.py +52 -2
- exonware/xwsystem/io/serialization/parsers/__init__.py +15 -0
- exonware/xwsystem/io/serialization/parsers/base.py +59 -0
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +61 -0
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +45 -0
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +53 -0
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +59 -0
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +51 -0
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +50 -0
- exonware/xwsystem/io/serialization/parsers/registry.py +90 -0
- exonware/xwsystem/io/serialization/parsers/standard.py +43 -0
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +50 -0
- exonware/xwsystem/io/serialization/registry.py +1 -1
- exonware/xwsystem/io/serialization/serializer.py +175 -3
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -1
- exonware/xwsystem/io/serialization/utils/path_ops.py +1 -1
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +1 -1
- exonware/xwsystem/io/stream/base.py +1 -1
- exonware/xwsystem/io/stream/codec_io.py +1 -1
- exonware/xwsystem/ipc/async_fabric.py +1 -2
- exonware/xwsystem/ipc/base.py +2 -2
- exonware/xwsystem/ipc/contracts.py +2 -2
- exonware/xwsystem/ipc/defs.py +1 -1
- exonware/xwsystem/ipc/errors.py +2 -2
- exonware/xwsystem/ipc/pipes.py +2 -2
- exonware/xwsystem/ipc/shared_memory.py +2 -2
- exonware/xwsystem/monitoring/base.py +2 -2
- exonware/xwsystem/monitoring/contracts.py +1 -1
- exonware/xwsystem/monitoring/defs.py +1 -1
- exonware/xwsystem/monitoring/error_recovery.py +2 -2
- exonware/xwsystem/monitoring/errors.py +2 -2
- exonware/xwsystem/monitoring/memory_monitor.py +1 -1
- exonware/xwsystem/monitoring/performance_manager_generic.py +2 -2
- exonware/xwsystem/monitoring/performance_validator.py +1 -1
- exonware/xwsystem/monitoring/system_monitor.py +2 -2
- exonware/xwsystem/monitoring/tracing.py +2 -2
- exonware/xwsystem/monitoring/tracker.py +1 -1
- exonware/xwsystem/operations/__init__.py +1 -1
- exonware/xwsystem/operations/base.py +1 -1
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +1 -1
- exonware/xwsystem/operations/merge.py +1 -1
- exonware/xwsystem/operations/patch.py +1 -1
- exonware/xwsystem/patterns/base.py +2 -2
- exonware/xwsystem/patterns/context_manager.py +2 -2
- exonware/xwsystem/patterns/contracts.py +9 -9
- exonware/xwsystem/patterns/defs.py +1 -1
- exonware/xwsystem/patterns/dynamic_facade.py +8 -8
- exonware/xwsystem/patterns/errors.py +5 -5
- exonware/xwsystem/patterns/handler_factory.py +6 -6
- exonware/xwsystem/patterns/object_pool.py +7 -7
- exonware/xwsystem/patterns/registry.py +3 -3
- exonware/xwsystem/plugins/__init__.py +1 -1
- exonware/xwsystem/plugins/base.py +5 -5
- exonware/xwsystem/plugins/contracts.py +5 -5
- exonware/xwsystem/plugins/defs.py +1 -1
- exonware/xwsystem/plugins/errors.py +4 -4
- exonware/xwsystem/runtime/__init__.py +1 -1
- exonware/xwsystem/runtime/base.py +6 -6
- exonware/xwsystem/runtime/contracts.py +6 -6
- exonware/xwsystem/runtime/defs.py +1 -1
- exonware/xwsystem/runtime/env.py +2 -2
- exonware/xwsystem/runtime/errors.py +1 -1
- exonware/xwsystem/runtime/reflection.py +8 -8
- exonware/xwsystem/security/auth.py +1 -1
- exonware/xwsystem/security/base.py +2 -2
- exonware/xwsystem/security/contracts.py +1 -1
- exonware/xwsystem/security/crypto.py +2 -2
- exonware/xwsystem/security/defs.py +1 -1
- exonware/xwsystem/security/errors.py +2 -2
- exonware/xwsystem/security/hazmat.py +2 -2
- exonware/xwsystem/shared/__init__.py +1 -1
- exonware/xwsystem/shared/base.py +1 -1
- exonware/xwsystem/shared/contracts.py +1 -1
- 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 +2 -2
- exonware/xwsystem/structures/contracts.py +1 -1
- exonware/xwsystem/structures/defs.py +1 -1
- exonware/xwsystem/structures/errors.py +2 -2
- exonware/xwsystem/threading/async_primitives.py +2 -2
- exonware/xwsystem/threading/base.py +2 -2
- exonware/xwsystem/threading/contracts.py +1 -1
- exonware/xwsystem/threading/defs.py +1 -1
- exonware/xwsystem/threading/errors.py +2 -2
- exonware/xwsystem/threading/safe_factory.py +6 -6
- exonware/xwsystem/utils/base.py +2 -2
- exonware/xwsystem/utils/contracts.py +1 -1
- exonware/xwsystem/utils/dt/__init__.py +1 -1
- exonware/xwsystem/utils/dt/base.py +2 -2
- exonware/xwsystem/utils/dt/contracts.py +1 -1
- exonware/xwsystem/utils/dt/defs.py +1 -1
- exonware/xwsystem/utils/dt/errors.py +2 -2
- exonware/xwsystem/utils/dt/formatting.py +1 -1
- exonware/xwsystem/utils/dt/humanize.py +2 -2
- exonware/xwsystem/utils/dt/parsing.py +1 -1
- exonware/xwsystem/utils/dt/timezone_utils.py +1 -1
- exonware/xwsystem/utils/errors.py +2 -2
- exonware/xwsystem/utils/utils_contracts.py +1 -1
- exonware/xwsystem/validation/__init__.py +1 -1
- exonware/xwsystem/validation/base.py +15 -15
- exonware/xwsystem/validation/contracts.py +1 -1
- exonware/xwsystem/validation/data_validator.py +10 -0
- exonware/xwsystem/validation/declarative.py +9 -9
- exonware/xwsystem/validation/defs.py +1 -1
- exonware/xwsystem/validation/errors.py +2 -2
- exonware/xwsystem/validation/fluent_validator.py +4 -4
- exonware/xwsystem/version.py +4 -4
- {exonware_xwsystem-0.0.1.410.dist-info → exonware_xwsystem-0.1.0.1.dist-info}/METADATA +3 -3
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +284 -0
- exonware/xwsystem/caching/USAGE_GUIDE.md +0 -779
- exonware/xwsystem/utils/test_runner.py +0 -526
- exonware_xwsystem-0.0.1.410.dist-info/RECORD +0 -273
- {exonware_xwsystem-0.0.1.410.dist-info → exonware_xwsystem-0.1.0.1.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.0.1.410.dist-info → exonware_xwsystem-0.1.0.1.dist-info}/licenses/LICENSE +0 -0
exonware/xwsystem/io/defs.py
CHANGED
exonware/xwsystem/io/errors.py
CHANGED
exonware/xwsystem/io/facade.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.1.0.1
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
XWIO - Main facade for all I/O operations (MANDATORY facade pattern).
|
|
@@ -92,7 +92,7 @@ class XWIO(AUnifiedIO):
|
|
|
92
92
|
|
|
93
93
|
with performance_monitor("file_open"):
|
|
94
94
|
# Ensure parent directory exists
|
|
95
|
-
if self.auto_create_dirs and mode in [FileMode.WRITE, FileMode.APPEND, FileMode.
|
|
95
|
+
if self.auto_create_dirs and mode in [FileMode.WRITE, FileMode.APPEND, FileMode.WRITE_READ]:
|
|
96
96
|
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
97
97
|
|
|
98
98
|
# Open file
|
|
@@ -2,7 +2,7 @@
|
|
|
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.1.0.1
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
XWFile - Concrete implementation of file operations.
|
|
@@ -72,11 +72,12 @@ class XWFile(AFile):
|
|
|
72
72
|
def open(self, mode: FileMode = FileMode.READ) -> None:
|
|
73
73
|
"""Open file with validation and monitoring."""
|
|
74
74
|
if self.validate_paths:
|
|
75
|
-
|
|
75
|
+
for_writing = mode in [FileMode.WRITE, FileMode.APPEND, FileMode.WRITE_READ, FileMode.BINARY_WRITE, FileMode.BINARY_APPEND, FileMode.BINARY_WRITE_READ]
|
|
76
|
+
self._path_validator.validate_path(self.file_path, for_writing=for_writing, create_dirs=self.auto_create_dirs)
|
|
76
77
|
|
|
77
78
|
with performance_monitor("file_open"):
|
|
78
79
|
# Ensure parent directory exists
|
|
79
|
-
if self.auto_create_dirs and mode in [FileMode.WRITE, FileMode.APPEND, FileMode.
|
|
80
|
+
if self.auto_create_dirs and mode in [FileMode.WRITE, FileMode.APPEND, FileMode.WRITE_READ]:
|
|
80
81
|
self.file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
81
82
|
|
|
82
83
|
# Open file
|
|
@@ -110,7 +111,7 @@ class XWFile(AFile):
|
|
|
110
111
|
def save(self, data: Any, **kwargs) -> bool:
|
|
111
112
|
"""Save data to file with atomic operations."""
|
|
112
113
|
if self.validate_paths:
|
|
113
|
-
self._path_validator.validate_path(self.file_path)
|
|
114
|
+
self._path_validator.validate_path(self.file_path, for_writing=True, create_dirs=True)
|
|
114
115
|
|
|
115
116
|
if self.validate_data:
|
|
116
117
|
self._data_validator.validate_data(data)
|
|
@@ -119,9 +120,10 @@ class XWFile(AFile):
|
|
|
119
120
|
try:
|
|
120
121
|
if self.use_atomic_operations:
|
|
121
122
|
# Use atomic file writer
|
|
122
|
-
|
|
123
|
+
mode = 'wb' if isinstance(data, bytes) else 'w'
|
|
124
|
+
with AtomicFileWriter(self.file_path, mode=mode, backup=self.auto_backup) as writer:
|
|
123
125
|
if isinstance(data, str):
|
|
124
|
-
writer.write(data
|
|
126
|
+
writer.write(data)
|
|
125
127
|
else:
|
|
126
128
|
writer.write(data)
|
|
127
129
|
else:
|
|
@@ -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.1.0.1
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Paged file source with MODULAR paging system.
|
|
@@ -154,3 +154,10 @@ class PagedFileSource(FileDataSource, IPagedDataSource[Union[bytes, str]]):
|
|
|
154
154
|
break
|
|
155
155
|
yield chunk
|
|
156
156
|
offset += len(chunk) if isinstance(chunk, (bytes, str)) else chunk_size
|
|
157
|
+
|
|
158
|
+
def get_page_count(self, page_size: int = 1024) -> int:
|
|
159
|
+
"""Get total number of pages."""
|
|
160
|
+
total_size = self.total_size
|
|
161
|
+
if total_size < 0:
|
|
162
|
+
return 0
|
|
163
|
+
return (total_size + page_size - 1) // page_size # Ceiling division
|
|
@@ -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.1.0.1
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Paging strategy registry - LIKE CodecRegistry!
|
|
@@ -18,7 +18,7 @@ Priority 4 (Performance): Fast strategy lookup
|
|
|
18
18
|
Priority 5 (Extensibility): Easy to add new strategies
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
from typing import Optional
|
|
21
|
+
from typing import Optional
|
|
22
22
|
from ...contracts import IPagingStrategy
|
|
23
23
|
from ...defs import PagingMode
|
|
24
24
|
|
|
@@ -46,10 +46,10 @@ class PagingStrategyRegistry:
|
|
|
46
46
|
|
|
47
47
|
def __init__(self):
|
|
48
48
|
"""Initialize registry."""
|
|
49
|
-
self._strategies: dict[str,
|
|
49
|
+
self._strategies: dict[str, type[IPagingStrategy]] = {}
|
|
50
50
|
self._instances: dict[str, IPagingStrategy] = {}
|
|
51
51
|
|
|
52
|
-
def register(self, strategy_class:
|
|
52
|
+
def register(self, strategy_class: type[IPagingStrategy]) -> None:
|
|
53
53
|
"""
|
|
54
54
|
Register a paging strategy.
|
|
55
55
|
|
|
@@ -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.1.0.1
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
File-based data source implementation.
|
|
@@ -66,12 +66,14 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
66
66
|
self._validate_path = validate_path
|
|
67
67
|
|
|
68
68
|
if validate_path:
|
|
69
|
-
# Use
|
|
69
|
+
# Use PathValidator for validation if available
|
|
70
70
|
try:
|
|
71
|
-
from
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
from ...security.path_validator import PathValidator
|
|
72
|
+
# Don't check existence during initialization - file may be created later
|
|
73
|
+
pv = PathValidator(check_existence=False)
|
|
74
|
+
# For write modes, allow creating the file (path doesn't exist yet)
|
|
75
|
+
for_writing = mode and ('w' in mode or 'a' in mode or '+' in mode)
|
|
76
|
+
pv.validate_path(str(self._path), for_writing=for_writing, create_dirs=True)
|
|
75
77
|
except ImportError:
|
|
76
78
|
pass
|
|
77
79
|
|
|
@@ -131,10 +133,19 @@ class FileDataSource(IDataSource[Union[bytes, str]]):
|
|
|
131
133
|
if atomic:
|
|
132
134
|
# Use AtomicFileWriter from common
|
|
133
135
|
from ..common.atomic import AtomicFileWriter
|
|
134
|
-
|
|
136
|
+
# Determine mode based on data type and stored mode
|
|
137
|
+
if isinstance(data, bytes):
|
|
138
|
+
# Binary mode
|
|
139
|
+
atomic_mode = 'wb'
|
|
140
|
+
encoding = None
|
|
141
|
+
else:
|
|
142
|
+
# Text mode
|
|
143
|
+
atomic_mode = 'w'
|
|
144
|
+
encoding = options.get('encoding', self._encoding or 'utf-8')
|
|
145
|
+
|
|
146
|
+
with AtomicFileWriter(self._path, mode=atomic_mode, encoding=encoding, backup=backup) as writer:
|
|
135
147
|
if isinstance(data, str):
|
|
136
|
-
|
|
137
|
-
writer.write(data.encode(encoding))
|
|
148
|
+
writer.write(data)
|
|
138
149
|
else:
|
|
139
150
|
writer.write(data)
|
|
140
151
|
else:
|
|
@@ -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.1.0.1
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Local filesystem implementation.
|
|
@@ -144,4 +144,12 @@ class LocalFileSystem(IFileSystem):
|
|
|
144
144
|
p = self._resolve_path(path)
|
|
145
145
|
p.parent.mkdir(parents=True, exist_ok=True)
|
|
146
146
|
p.write_bytes(content)
|
|
147
|
+
|
|
148
|
+
def read(self, path: str) -> bytes:
|
|
149
|
+
"""Read file contents."""
|
|
150
|
+
return self.read_bytes(path)
|
|
151
|
+
|
|
152
|
+
def write(self, path: str, content: bytes) -> None:
|
|
153
|
+
"""Write file contents."""
|
|
154
|
+
self.write_bytes(path, content)
|
|
147
155
|
|
|
@@ -2,7 +2,7 @@
|
|
|
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.1.0.1
|
|
6
6
|
Generation Date: September 04, 2025
|
|
7
7
|
|
|
8
8
|
XWFolder - Concrete implementation of folder operations.
|
|
@@ -65,7 +65,7 @@ class XWFolder(AFolder):
|
|
|
65
65
|
def create(self, parents: bool = True, exist_ok: bool = True) -> bool:
|
|
66
66
|
"""Create directory with validation."""
|
|
67
67
|
if self.validate_paths:
|
|
68
|
-
self._path_validator.validate_path(self.dir_path)
|
|
68
|
+
self._path_validator.validate_path(self.dir_path, for_writing=True, create_dirs=parents)
|
|
69
69
|
|
|
70
70
|
with performance_monitor("directory_create"):
|
|
71
71
|
try:
|
|
@@ -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.1.0.1
|
|
7
7
|
Generation Date: September 04, 2025
|
|
8
8
|
|
|
9
9
|
Automatic serializer that detects format and delegates to appropriate serializer.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import Any, Optional,
|
|
13
|
+
from typing import Any, Optional, Union
|
|
14
14
|
|
|
15
15
|
from .format_detector import FormatDetector, detect_format
|
|
16
16
|
from .contracts import ISerialization
|
|
@@ -39,7 +39,7 @@ class AutoSerializer:
|
|
|
39
39
|
self._serializer_cache: dict[str, ISerialization] = {}
|
|
40
40
|
self._default_format = default_format
|
|
41
41
|
|
|
42
|
-
def _get_serializer_class(self, format_name: str) ->
|
|
42
|
+
def _get_serializer_class(self, format_name: str) -> type[ISerialization]:
|
|
43
43
|
"""
|
|
44
44
|
Get serializer class for format name.
|
|
45
45
|
|
|
@@ -52,36 +52,45 @@ class AutoSerializer:
|
|
|
52
52
|
Raises:
|
|
53
53
|
ImportError: If format not available
|
|
54
54
|
"""
|
|
55
|
-
# Dynamic import to avoid circular dependencies
|
|
55
|
+
# Dynamic import to avoid circular dependencies.
|
|
56
|
+
# Root cause fix: import concrete serializers from the canonical
|
|
57
|
+
# xwsystem.io.serialization.formats packages instead of a parallel
|
|
58
|
+
# exonware.xwsystem.serialization namespace (which should not exist).
|
|
56
59
|
module_map = {
|
|
57
|
-
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
'
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
'
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
'
|
|
60
|
+
# Text formats
|
|
61
|
+
'JSON': ('io.serialization.formats.text.json', 'JsonSerializer'),
|
|
62
|
+
'JSONL': ('io.serialization.formats.text.jsonlines', 'JsonLinesSerializer'),
|
|
63
|
+
'NDJSON': ('io.serialization.formats.text.jsonlines', 'JsonLinesSerializer'),
|
|
64
|
+
'YAML': ('io.serialization.formats.text.yaml', 'YamlSerializer'),
|
|
65
|
+
'TOML': ('io.serialization.formats.text.toml', 'TomlSerializer'),
|
|
66
|
+
'XML': ('io.serialization.formats.text.xml', 'XmlSerializer'),
|
|
67
|
+
'CSV': ('io.serialization.formats.text.csv', 'CsvSerializer'),
|
|
68
|
+
'ConfigParser': ('io.serialization.formats.text.configparser', 'ConfigParserSerializer'),
|
|
69
|
+
'FormData': ('io.serialization.formats.text.formdata', 'FormDataSerializer'),
|
|
70
|
+
'Multipart': ('io.serialization.formats.text.multipart', 'MultipartSerializer'),
|
|
71
|
+
|
|
72
|
+
# Binary / database formats
|
|
73
|
+
'BSON': ('io.serialization.formats.binary.bson', 'BsonSerializer'),
|
|
74
|
+
'MessagePack': ('io.serialization.formats.binary.msgpack', 'MsgPackSerializer'),
|
|
75
|
+
'CBOR': ('io.serialization.formats.binary.cbor', 'CborSerializer'),
|
|
76
|
+
'Pickle': ('io.serialization.formats.binary.pickle', 'PickleSerializer'),
|
|
77
|
+
'Marshal': ('io.serialization.formats.binary.marshal', 'MarshalSerializer'),
|
|
78
|
+
'SQLite3': ('io.serialization.formats.database.sqlite3', 'Sqlite3Serializer'),
|
|
79
|
+
'DBM': ('io.serialization.formats.database.dbm', 'DbmSerializer'),
|
|
80
|
+
'Shelve': ('io.serialization.formats.database.shelve', 'ShelveSerializer'),
|
|
81
|
+
'Plistlib': ('io.serialization.formats.binary.plistlib', 'PlistSerializer'),
|
|
82
|
+
|
|
83
|
+
# Schema-based / advanced formats (placeholders for future modules)
|
|
84
|
+
# These entries intentionally point to non-existent modules today.
|
|
85
|
+
# The lazy installation system will handle installing/adding them
|
|
86
|
+
# when the corresponding format implementations are introduced.
|
|
87
|
+
'Avro': ('io.serialization.formats.schema.avro', 'AvroSerializer'),
|
|
88
|
+
'Protobuf': ('io.serialization.formats.schema.protobuf', 'ProtobufSerializer'),
|
|
89
|
+
'Thrift': ('io.serialization.formats.schema.thrift', 'ThriftSerializer'),
|
|
90
|
+
'Parquet': ('io.serialization.formats.scientific.parquet', 'ParquetSerializer'),
|
|
91
|
+
'ORC': ('io.serialization.formats.scientific.orc', 'OrcSerializer'),
|
|
92
|
+
'CapnProto': ('io.serialization.formats.schema.capnproto', 'CapnProtoSerializer'),
|
|
93
|
+
'FlatBuffers': ('io.serialization.formats.schema.flatbuffers', 'FlatBuffersSerializer'),
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
if format_name not in module_map:
|
|
@@ -90,9 +99,9 @@ class AutoSerializer:
|
|
|
90
99
|
module_name, class_name = module_map[format_name]
|
|
91
100
|
|
|
92
101
|
try:
|
|
93
|
-
# Import from
|
|
94
|
-
module = __import__(f'exonware.xwsystem.
|
|
95
|
-
|
|
102
|
+
# Import from canonical xwsystem.io serialization path
|
|
103
|
+
module = __import__(f'exonware.xwsystem.{module_name}',
|
|
104
|
+
fromlist=[class_name])
|
|
96
105
|
return getattr(module, class_name)
|
|
97
106
|
except (ImportError, AttributeError) as e:
|
|
98
107
|
# Lazy installation system will handle missing dependencies
|
|
@@ -119,7 +128,8 @@ class AutoSerializer:
|
|
|
119
128
|
self,
|
|
120
129
|
data: Any,
|
|
121
130
|
file_path: Optional[Union[str, Path]] = None,
|
|
122
|
-
format_hint: Optional[str] = None
|
|
131
|
+
format_hint: Optional[str] = None,
|
|
132
|
+
**opts
|
|
123
133
|
) -> Union[str, bytes]:
|
|
124
134
|
"""
|
|
125
135
|
Auto-detect format and serialize data.
|
|
@@ -128,6 +138,7 @@ class AutoSerializer:
|
|
|
128
138
|
data: Data to serialize
|
|
129
139
|
file_path: Optional file path for format detection
|
|
130
140
|
format_hint: Optional format hint to use
|
|
141
|
+
**opts: Additional serializer-specific options (pretty, indent, etc.)
|
|
131
142
|
|
|
132
143
|
Returns:
|
|
133
144
|
Serialized data
|
|
@@ -145,7 +156,7 @@ class AutoSerializer:
|
|
|
145
156
|
logger.debug(f"Using default format: {format_name}")
|
|
146
157
|
|
|
147
158
|
serializer = self._get_serializer(format_name)
|
|
148
|
-
return serializer.dumps(data)
|
|
159
|
+
return serializer.dumps(data, **opts)
|
|
149
160
|
|
|
150
161
|
def detect_and_deserialize(
|
|
151
162
|
self,
|
|
@@ -362,7 +373,8 @@ _global_auto_serializer = AutoSerializer()
|
|
|
362
373
|
def auto_serialize(
|
|
363
374
|
data: Any,
|
|
364
375
|
file_path: Optional[Union[str, Path]] = None,
|
|
365
|
-
format_hint: Optional[str] = None
|
|
376
|
+
format_hint: Optional[str] = None,
|
|
377
|
+
**opts
|
|
366
378
|
) -> Union[str, bytes]:
|
|
367
379
|
"""
|
|
368
380
|
Convenience function for auto-serialization.
|
|
@@ -371,11 +383,12 @@ def auto_serialize(
|
|
|
371
383
|
data: Data to serialize
|
|
372
384
|
file_path: Optional file path for format detection
|
|
373
385
|
format_hint: Optional format hint
|
|
386
|
+
**opts: Additional serializer options
|
|
374
387
|
|
|
375
388
|
Returns:
|
|
376
389
|
Serialized data
|
|
377
390
|
"""
|
|
378
|
-
return _global_auto_serializer.detect_and_serialize(data, file_path, format_hint)
|
|
391
|
+
return _global_auto_serializer.detect_and_serialize(data, file_path, format_hint, **opts)
|
|
379
392
|
|
|
380
393
|
def auto_deserialize(
|
|
381
394
|
data: Union[str, bytes],
|