exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__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 -1
- exonware/conf.py +2 -2
- exonware/xwsystem/__init__.py +115 -43
- exonware/xwsystem/base.py +30 -0
- exonware/xwsystem/caching/__init__.py +39 -13
- exonware/xwsystem/caching/base.py +24 -6
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +2 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +85 -139
- exonware/xwsystem/caching/decorators.py +6 -19
- exonware/xwsystem/caching/defs.py +2 -1
- exonware/xwsystem/caching/disk_cache.py +2 -1
- exonware/xwsystem/caching/distributed.py +2 -1
- exonware/xwsystem/caching/errors.py +2 -1
- exonware/xwsystem/caching/events.py +110 -27
- exonware/xwsystem/caching/eviction_strategies.py +2 -2
- exonware/xwsystem/caching/external_caching_python.py +701 -0
- exonware/xwsystem/caching/facade.py +253 -0
- exonware/xwsystem/caching/factory.py +300 -0
- exonware/xwsystem/caching/fluent.py +14 -12
- exonware/xwsystem/caching/integrity.py +21 -6
- exonware/xwsystem/caching/lfu_cache.py +2 -1
- exonware/xwsystem/caching/lfu_optimized.py +18 -6
- exonware/xwsystem/caching/lru_cache.py +7 -4
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +2 -2
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +2 -2
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +81 -28
- exonware/xwsystem/caching/serializable.py +9 -7
- exonware/xwsystem/caching/stats.py +2 -2
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +4 -3
- exonware/xwsystem/caching/two_tier_cache.py +6 -3
- exonware/xwsystem/caching/utils.py +30 -12
- exonware/xwsystem/caching/validation.py +2 -2
- exonware/xwsystem/caching/warming.py +6 -3
- exonware/xwsystem/caching/write_behind.py +15 -6
- exonware/xwsystem/config/__init__.py +11 -17
- exonware/xwsystem/config/base.py +5 -5
- exonware/xwsystem/config/contracts.py +93 -153
- exonware/xwsystem/config/defaults.py +3 -2
- exonware/xwsystem/config/defs.py +3 -2
- exonware/xwsystem/config/errors.py +2 -5
- exonware/xwsystem/config/logging.py +12 -8
- exonware/xwsystem/config/logging_setup.py +3 -2
- exonware/xwsystem/config/performance.py +1 -46
- exonware/xwsystem/config/performance_modes.py +9 -8
- exonware/xwsystem/config/version_manager.py +1 -0
- exonware/xwsystem/config.py +27 -0
- exonware/xwsystem/console/__init__.py +53 -0
- exonware/xwsystem/console/base.py +133 -0
- exonware/xwsystem/console/cli/__init__.py +61 -0
- exonware/xwsystem/{cli → console/cli}/args.py +27 -24
- exonware/xwsystem/{cli → console/cli}/base.py +18 -87
- exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
- exonware/xwsystem/console/cli/console.py +98 -0
- exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
- exonware/xwsystem/console/cli/defs.py +87 -0
- exonware/xwsystem/console/cli/encoding.py +69 -0
- exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
- exonware/xwsystem/console/cli/event_logger.py +166 -0
- exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
- exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
- exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
- exonware/xwsystem/console/contracts.py +113 -0
- exonware/xwsystem/console/defs.py +154 -0
- exonware/xwsystem/console/errors.py +34 -0
- exonware/xwsystem/console/event_logger.py +385 -0
- exonware/xwsystem/console/writer.py +132 -0
- exonware/xwsystem/contracts.py +28 -0
- exonware/xwsystem/data_structures/__init__.py +23 -0
- exonware/xwsystem/data_structures/trie.py +34 -0
- exonware/xwsystem/data_structures/union_find.py +144 -0
- exonware/xwsystem/defs.py +17 -0
- exonware/xwsystem/errors.py +23 -0
- exonware/xwsystem/facade.py +62 -0
- exonware/xwsystem/http_client/__init__.py +22 -1
- exonware/xwsystem/http_client/advanced_client.py +8 -5
- exonware/xwsystem/http_client/base.py +3 -2
- exonware/xwsystem/http_client/client.py +7 -4
- exonware/xwsystem/http_client/contracts.py +42 -56
- exonware/xwsystem/http_client/defs.py +2 -1
- exonware/xwsystem/http_client/errors.py +2 -1
- exonware/xwsystem/http_client/facade.py +156 -0
- exonware/xwsystem/io/__init__.py +22 -3
- exonware/xwsystem/io/archive/__init__.py +8 -2
- exonware/xwsystem/io/archive/archive.py +1 -1
- exonware/xwsystem/io/archive/archive_files.py +4 -7
- exonware/xwsystem/io/archive/archivers.py +120 -10
- exonware/xwsystem/io/archive/base.py +4 -5
- exonware/xwsystem/io/archive/codec_integration.py +1 -2
- exonware/xwsystem/io/archive/compression.py +1 -2
- exonware/xwsystem/io/archive/facade.py +263 -0
- exonware/xwsystem/io/archive/formats/__init__.py +2 -3
- exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
- exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
- exonware/xwsystem/io/archive/formats/rar.py +11 -5
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
- exonware/xwsystem/io/archive/formats/tar.py +52 -7
- exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
- exonware/xwsystem/io/archive/formats/zip.py +1 -2
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
- exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
- exonware/xwsystem/io/base.py +119 -115
- exonware/xwsystem/io/codec/__init__.py +4 -2
- exonware/xwsystem/io/codec/base.py +19 -13
- exonware/xwsystem/io/codec/contracts.py +59 -2
- exonware/xwsystem/io/codec/registry.py +67 -21
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +29 -16
- exonware/xwsystem/io/common/base.py +11 -10
- exonware/xwsystem/io/common/lock.py +6 -5
- exonware/xwsystem/io/common/path_manager.py +2 -1
- exonware/xwsystem/io/common/watcher.py +1 -2
- exonware/xwsystem/io/contracts.py +301 -433
- exonware/xwsystem/io/contracts_1.py +1180 -0
- exonware/xwsystem/io/data_operations.py +19 -20
- exonware/xwsystem/io/defs.py +4 -3
- exonware/xwsystem/io/errors.py +3 -2
- exonware/xwsystem/io/facade.py +87 -61
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +8 -9
- exonware/xwsystem/io/file/conversion.py +2 -3
- exonware/xwsystem/io/file/file.py +61 -18
- exonware/xwsystem/io/file/paged_source.py +8 -8
- exonware/xwsystem/io/file/paging/__init__.py +1 -2
- exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
- exonware/xwsystem/io/file/paging/line_paging.py +2 -3
- exonware/xwsystem/io/file/paging/record_paging.py +2 -3
- exonware/xwsystem/io/file/paging/registry.py +1 -2
- exonware/xwsystem/io/file/source.py +13 -17
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -2
- exonware/xwsystem/io/filesystem/local.py +3 -4
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +1 -2
- exonware/xwsystem/io/folder/folder.py +16 -7
- exonware/xwsystem/io/indexing/__init__.py +14 -0
- exonware/xwsystem/io/indexing/facade.py +443 -0
- exonware/xwsystem/io/path_parser.py +98 -0
- exonware/xwsystem/io/serialization/__init__.py +21 -3
- exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
- exonware/xwsystem/io/serialization/base.py +84 -34
- exonware/xwsystem/io/serialization/contracts.py +50 -73
- exonware/xwsystem/io/serialization/defs.py +2 -1
- exonware/xwsystem/io/serialization/errors.py +2 -1
- exonware/xwsystem/io/serialization/flyweight.py +154 -7
- exonware/xwsystem/io/serialization/format_detector.py +15 -14
- exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
- exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
- exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
- exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
- exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
- exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
- exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
- exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
- exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
- exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
- exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
- exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
- exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
- exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
- exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
- exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
- exonware/xwsystem/io/serialization/parsers/base.py +6 -5
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
- exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
- exonware/xwsystem/io/serialization/registry.py +4 -4
- exonware/xwsystem/io/serialization/serializer.py +168 -79
- exonware/xwsystem/io/serialization/universal_options.py +367 -0
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
- exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
- exonware/xwsystem/io/source_reader.py +223 -0
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +61 -14
- exonware/xwsystem/io/stream/base.py +1 -2
- exonware/xwsystem/io/stream/codec_io.py +6 -7
- exonware/xwsystem/ipc/__init__.py +1 -0
- exonware/xwsystem/ipc/async_fabric.py +4 -4
- exonware/xwsystem/ipc/base.py +6 -5
- exonware/xwsystem/ipc/contracts.py +41 -66
- exonware/xwsystem/ipc/defs.py +2 -1
- exonware/xwsystem/ipc/errors.py +2 -1
- exonware/xwsystem/ipc/message_queue.py +5 -2
- exonware/xwsystem/ipc/pipes.py +70 -34
- exonware/xwsystem/ipc/process_manager.py +7 -5
- exonware/xwsystem/ipc/process_pool.py +6 -5
- exonware/xwsystem/ipc/shared_memory.py +64 -11
- exonware/xwsystem/monitoring/__init__.py +7 -0
- exonware/xwsystem/monitoring/base.py +11 -8
- exonware/xwsystem/monitoring/contracts.py +86 -144
- exonware/xwsystem/monitoring/defs.py +2 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -3
- exonware/xwsystem/monitoring/errors.py +2 -1
- exonware/xwsystem/monitoring/facade.py +183 -0
- exonware/xwsystem/monitoring/memory_monitor.py +1 -0
- exonware/xwsystem/monitoring/metrics.py +1 -0
- exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
- exonware/xwsystem/monitoring/performance_monitor.py +1 -0
- exonware/xwsystem/monitoring/performance_validator.py +1 -0
- exonware/xwsystem/monitoring/system_monitor.py +6 -5
- exonware/xwsystem/monitoring/tracing.py +18 -16
- exonware/xwsystem/monitoring/tracker.py +2 -1
- exonware/xwsystem/operations/__init__.py +5 -50
- exonware/xwsystem/operations/base.py +3 -44
- exonware/xwsystem/operations/contracts.py +25 -15
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +5 -4
- exonware/xwsystem/operations/errors.py +1 -1
- exonware/xwsystem/operations/merge.py +6 -4
- exonware/xwsystem/operations/patch.py +5 -4
- exonware/xwsystem/patterns/__init__.py +1 -0
- exonware/xwsystem/patterns/base.py +2 -1
- exonware/xwsystem/patterns/context_manager.py +2 -1
- exonware/xwsystem/patterns/contracts.py +215 -256
- exonware/xwsystem/patterns/defs.py +2 -1
- exonware/xwsystem/patterns/dynamic_facade.py +1 -0
- exonware/xwsystem/patterns/errors.py +2 -4
- exonware/xwsystem/patterns/handler_factory.py +2 -3
- exonware/xwsystem/patterns/import_registry.py +1 -0
- exonware/xwsystem/patterns/object_pool.py +1 -0
- exonware/xwsystem/patterns/registry.py +4 -43
- exonware/xwsystem/plugins/__init__.py +2 -1
- exonware/xwsystem/plugins/base.py +6 -5
- exonware/xwsystem/plugins/contracts.py +94 -158
- exonware/xwsystem/plugins/defs.py +2 -1
- exonware/xwsystem/plugins/errors.py +2 -1
- exonware/xwsystem/py.typed +3 -0
- exonware/xwsystem/query/__init__.py +36 -0
- exonware/xwsystem/query/contracts.py +56 -0
- exonware/xwsystem/query/errors.py +22 -0
- exonware/xwsystem/query/registry.py +128 -0
- exonware/xwsystem/runtime/__init__.py +2 -1
- exonware/xwsystem/runtime/base.py +4 -3
- exonware/xwsystem/runtime/contracts.py +39 -60
- exonware/xwsystem/runtime/defs.py +2 -1
- exonware/xwsystem/runtime/env.py +11 -9
- exonware/xwsystem/runtime/errors.py +2 -1
- exonware/xwsystem/runtime/reflection.py +3 -2
- exonware/xwsystem/security/__init__.py +68 -11
- exonware/xwsystem/security/audit.py +167 -0
- exonware/xwsystem/security/base.py +121 -24
- exonware/xwsystem/security/contracts.py +91 -146
- exonware/xwsystem/security/crypto.py +17 -16
- exonware/xwsystem/security/defs.py +2 -1
- exonware/xwsystem/security/errors.py +2 -1
- exonware/xwsystem/security/facade.py +321 -0
- exonware/xwsystem/security/file_security.py +330 -0
- exonware/xwsystem/security/hazmat.py +11 -8
- exonware/xwsystem/security/monitor.py +372 -0
- exonware/xwsystem/security/path_validator.py +140 -18
- exonware/xwsystem/security/policy.py +357 -0
- exonware/xwsystem/security/resource_limits.py +1 -0
- exonware/xwsystem/security/validator.py +455 -0
- exonware/xwsystem/shared/__init__.py +14 -1
- exonware/xwsystem/shared/base.py +285 -2
- exonware/xwsystem/shared/contracts.py +415 -126
- exonware/xwsystem/shared/defs.py +2 -1
- exonware/xwsystem/shared/errors.py +2 -2
- exonware/xwsystem/shared/xwobject.py +316 -0
- exonware/xwsystem/structures/__init__.py +1 -0
- exonware/xwsystem/structures/base.py +3 -2
- exonware/xwsystem/structures/circular_detector.py +15 -14
- exonware/xwsystem/structures/contracts.py +53 -76
- exonware/xwsystem/structures/defs.py +2 -1
- exonware/xwsystem/structures/errors.py +2 -1
- exonware/xwsystem/structures/tree_walker.py +2 -1
- exonware/xwsystem/threading/__init__.py +21 -4
- exonware/xwsystem/threading/async_primitives.py +6 -5
- exonware/xwsystem/threading/base.py +3 -2
- exonware/xwsystem/threading/contracts.py +87 -143
- exonware/xwsystem/threading/defs.py +2 -1
- exonware/xwsystem/threading/errors.py +2 -1
- exonware/xwsystem/threading/facade.py +175 -0
- exonware/xwsystem/threading/locks.py +1 -0
- exonware/xwsystem/threading/safe_factory.py +1 -0
- exonware/xwsystem/utils/__init__.py +40 -0
- exonware/xwsystem/utils/base.py +22 -21
- exonware/xwsystem/utils/contracts.py +50 -73
- exonware/xwsystem/utils/dt/__init__.py +19 -3
- exonware/xwsystem/utils/dt/base.py +5 -4
- exonware/xwsystem/utils/dt/contracts.py +22 -29
- exonware/xwsystem/utils/dt/defs.py +2 -1
- exonware/xwsystem/utils/dt/errors.py +2 -5
- exonware/xwsystem/utils/dt/formatting.py +88 -2
- exonware/xwsystem/utils/dt/humanize.py +10 -9
- exonware/xwsystem/utils/dt/parsing.py +56 -5
- exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
- exonware/xwsystem/utils/errors.py +2 -4
- exonware/xwsystem/utils/paths.py +1 -0
- exonware/xwsystem/utils/string.py +49 -0
- exonware/xwsystem/utils/test_runner.py +185 -0
- exonware/xwsystem/utils/utils_contracts.py +2 -1
- exonware/xwsystem/utils/web.py +110 -0
- exonware/xwsystem/validation/__init__.py +25 -1
- exonware/xwsystem/validation/base.py +6 -5
- exonware/xwsystem/validation/contracts.py +29 -41
- exonware/xwsystem/validation/data_validator.py +1 -0
- exonware/xwsystem/validation/declarative.py +11 -8
- exonware/xwsystem/validation/defs.py +2 -1
- exonware/xwsystem/validation/errors.py +2 -1
- exonware/xwsystem/validation/facade.py +198 -0
- exonware/xwsystem/validation/fluent_validator.py +22 -19
- exonware/xwsystem/validation/schema_discovery.py +210 -0
- exonware/xwsystem/validation/type_safety.py +2 -1
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
- exonware/xwsystem/cli/__init__.py +0 -43
- exonware/xwsystem/cli/console.py +0 -113
- exonware/xwsystem/cli/defs.py +0 -134
- exonware/xwsystem/conf.py +0 -44
- exonware/xwsystem/security/auth.py +0 -484
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/http_client/facade.py
|
|
2
|
+
"""
|
|
3
|
+
Company: eXonware.com
|
|
4
|
+
Author: Eng. Muhammad AlShehri
|
|
5
|
+
Email: connect@exonware.com
|
|
6
|
+
Version: 0.1.0.4
|
|
7
|
+
Generation Date: January 2026
|
|
8
|
+
|
|
9
|
+
XWHTTP - Unified HTTP Client Facade
|
|
10
|
+
|
|
11
|
+
Simplified API for HTTP operations:
|
|
12
|
+
- Simple requests (GET, POST, PUT, DELETE, etc.)
|
|
13
|
+
- Client instances with configuration
|
|
14
|
+
- Async support
|
|
15
|
+
- Retry logic
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import Any, Optional, Dict
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
from .client import HttpClient, AsyncHttpClient, HttpError, RetryConfig
|
|
22
|
+
from .advanced_client import AdvancedHttpClient, AdvancedHttpConfig
|
|
23
|
+
from ..config.logging_setup import get_logger
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class XWHTTP:
|
|
29
|
+
"""
|
|
30
|
+
Unified HTTP client facade - simple API for HTTP operations.
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
>>> # Simple requests
|
|
34
|
+
>>> response = XWHTTP.get("https://api.example.com/data")
|
|
35
|
+
>>> response = XWHTTP.post("https://api.example.com/users", json={"name": "John"})
|
|
36
|
+
|
|
37
|
+
>>> # Client instance
|
|
38
|
+
>>> client = XWHTTP(base_url="https://api.example.com", timeout=30)
|
|
39
|
+
>>> response = client.get("/users")
|
|
40
|
+
>>> response = client.post("/users", json=data)
|
|
41
|
+
|
|
42
|
+
>>> # Async
|
|
43
|
+
>>> async def fetch():
|
|
44
|
+
... async with XWHTTP() as client:
|
|
45
|
+
... response = await client.get("https://api.example.com")
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
base_url: Optional[str] = None,
|
|
51
|
+
timeout: int = 30,
|
|
52
|
+
retries: int = 3,
|
|
53
|
+
async_mode: bool = False,
|
|
54
|
+
**kwargs
|
|
55
|
+
):
|
|
56
|
+
"""
|
|
57
|
+
Initialize HTTP client.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
base_url: Base URL for all requests
|
|
61
|
+
timeout: Request timeout in seconds
|
|
62
|
+
retries: Number of retry attempts
|
|
63
|
+
async_mode: Use async client
|
|
64
|
+
**kwargs: Additional client configuration
|
|
65
|
+
"""
|
|
66
|
+
self.base_url = base_url
|
|
67
|
+
self.timeout = timeout
|
|
68
|
+
self.retries = retries
|
|
69
|
+
self.async_mode = async_mode
|
|
70
|
+
self.kwargs = kwargs
|
|
71
|
+
|
|
72
|
+
# Create client instance
|
|
73
|
+
if async_mode:
|
|
74
|
+
self._client = AsyncHttpClient(
|
|
75
|
+
base_url=base_url,
|
|
76
|
+
timeout=timeout,
|
|
77
|
+
retry_config=RetryConfig(max_retries=retries),
|
|
78
|
+
**kwargs
|
|
79
|
+
)
|
|
80
|
+
else:
|
|
81
|
+
self._client = HttpClient(
|
|
82
|
+
base_url=base_url,
|
|
83
|
+
timeout=timeout,
|
|
84
|
+
retry_config=RetryConfig(max_retries=retries),
|
|
85
|
+
**kwargs
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def get(self, url: str, **kwargs) -> Any:
|
|
89
|
+
"""GET request."""
|
|
90
|
+
full_url = self._build_url(url)
|
|
91
|
+
return self._client.get(full_url, **kwargs)
|
|
92
|
+
|
|
93
|
+
def post(self, url: str, **kwargs) -> Any:
|
|
94
|
+
"""POST request."""
|
|
95
|
+
full_url = self._build_url(url)
|
|
96
|
+
return self._client.post(full_url, **kwargs)
|
|
97
|
+
|
|
98
|
+
def put(self, url: str, **kwargs) -> Any:
|
|
99
|
+
"""PUT request."""
|
|
100
|
+
full_url = self._build_url(url)
|
|
101
|
+
return self._client.put(full_url, **kwargs)
|
|
102
|
+
|
|
103
|
+
def delete(self, url: str, **kwargs) -> Any:
|
|
104
|
+
"""DELETE request."""
|
|
105
|
+
full_url = self._build_url(url)
|
|
106
|
+
return self._client.delete(full_url, **kwargs)
|
|
107
|
+
|
|
108
|
+
def patch(self, url: str, **kwargs) -> Any:
|
|
109
|
+
"""PATCH request."""
|
|
110
|
+
full_url = self._build_url(url)
|
|
111
|
+
return self._client.patch(full_url, **kwargs)
|
|
112
|
+
|
|
113
|
+
def _build_url(self, url: str) -> str:
|
|
114
|
+
"""Build full URL from base_url and relative URL."""
|
|
115
|
+
if self.base_url and not url.startswith(("http://", "https://")):
|
|
116
|
+
return f"{self.base_url.rstrip('/')}/{url.lstrip('/')}"
|
|
117
|
+
return url
|
|
118
|
+
|
|
119
|
+
def __enter__(self):
|
|
120
|
+
"""Context manager entry."""
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
124
|
+
"""Context manager exit."""
|
|
125
|
+
# Clients handle their own cleanup
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
def get(url: str, **kwargs) -> Any:
|
|
130
|
+
"""Static GET request."""
|
|
131
|
+
client = HttpClient()
|
|
132
|
+
return client.get(url, **kwargs)
|
|
133
|
+
|
|
134
|
+
@staticmethod
|
|
135
|
+
def post(url: str, **kwargs) -> Any:
|
|
136
|
+
"""Static POST request."""
|
|
137
|
+
client = HttpClient()
|
|
138
|
+
return client.post(url, **kwargs)
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def put(url: str, **kwargs) -> Any:
|
|
142
|
+
"""Static PUT request."""
|
|
143
|
+
client = HttpClient()
|
|
144
|
+
return client.put(url, **kwargs)
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def delete(url: str, **kwargs) -> Any:
|
|
148
|
+
"""Static DELETE request."""
|
|
149
|
+
client = HttpClient()
|
|
150
|
+
return client.delete(url, **kwargs)
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def patch(url: str, **kwargs) -> Any:
|
|
154
|
+
"""Static PATCH request."""
|
|
155
|
+
client = HttpClient()
|
|
156
|
+
return client.patch(url, **kwargs)
|
exonware/xwsystem/io/__init__.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/io/__init__.py
|
|
1
2
|
"""
|
|
2
3
|
Company: eXonware.com
|
|
3
4
|
Author: Eng. Muhammad AlShehri
|
|
4
5
|
Email: connect@exonware.com
|
|
5
|
-
Version: 0.1.0.
|
|
6
|
+
Version: 0.1.0.4
|
|
6
7
|
Generation Date: 30-Oct-2025
|
|
7
8
|
|
|
8
9
|
I/O utilities for safe file operations, path management, and codec integration.
|
|
@@ -94,6 +95,18 @@ from .file import (
|
|
|
94
95
|
|
|
95
96
|
from .folder import XWFolder
|
|
96
97
|
|
|
98
|
+
# ═══════════════════════════════════════════════════════════════════════
|
|
99
|
+
# SOURCE READER - Load from path or URL (local + internet)
|
|
100
|
+
# ═══════════════════════════════════════════════════════════════════════
|
|
101
|
+
|
|
102
|
+
from .source_reader import (
|
|
103
|
+
SourceLoadConfig,
|
|
104
|
+
is_http_url,
|
|
105
|
+
get_scheme,
|
|
106
|
+
is_external_scheme,
|
|
107
|
+
read_source_text,
|
|
108
|
+
)
|
|
109
|
+
|
|
97
110
|
# ═══════════════════════════════════════════════════════════════════════
|
|
98
111
|
# STREAM - Stream + Codec Integration
|
|
99
112
|
# ═══════════════════════════════════════════════════════════════════════
|
|
@@ -113,7 +126,7 @@ from .filesystem import LocalFileSystem
|
|
|
113
126
|
# ═══════════════════════════════════════════════════════════════════════
|
|
114
127
|
|
|
115
128
|
from .archive import (
|
|
116
|
-
#
|
|
129
|
+
# Archive
|
|
117
130
|
Archive, Compression,
|
|
118
131
|
# Archivers (Codecs - In-memory)
|
|
119
132
|
ZipArchiver, TarArchiver,
|
|
@@ -138,7 +151,6 @@ from .codec.contracts import ICodec, ICodecMetadata
|
|
|
138
151
|
from .codec.base import ACodec
|
|
139
152
|
from .codec.registry import UniversalCodecRegistry, get_registry
|
|
140
153
|
|
|
141
|
-
# Type aliases for backward compatibility
|
|
142
154
|
from .contracts import EncodeOptions, DecodeOptions, Serializer, Formatter
|
|
143
155
|
|
|
144
156
|
# ═══════════════════════════════════════════════════════════════════════
|
|
@@ -192,6 +204,13 @@ __all__ = [
|
|
|
192
204
|
# Folder operations
|
|
193
205
|
"XWFolder",
|
|
194
206
|
|
|
207
|
+
# Source reader (path or URI; config-driven, multi-scheme)
|
|
208
|
+
"SourceLoadConfig",
|
|
209
|
+
"is_http_url",
|
|
210
|
+
"get_scheme",
|
|
211
|
+
"is_external_scheme",
|
|
212
|
+
"read_source_text",
|
|
213
|
+
|
|
195
214
|
# Stream operations
|
|
196
215
|
"CodecIO", "PagedCodecIO", "AsyncAtomicFileWriter",
|
|
197
216
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Archive and compression with REGISTRY PATTERN!
|
|
@@ -118,4 +118,10 @@ __all__ = [
|
|
|
118
118
|
# Facades
|
|
119
119
|
"Archive",
|
|
120
120
|
"Compression",
|
|
121
|
-
|
|
121
|
+
|
|
122
|
+
# Unified Facade
|
|
123
|
+
"XWArchive",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
# Import unified facade
|
|
127
|
+
from .facade import XWArchive
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Archive FILES - File persistence for archives.
|
|
@@ -26,7 +26,7 @@ Priority 5 (Extensibility): Easy to add new formats
|
|
|
26
26
|
import zipfile
|
|
27
27
|
import tarfile
|
|
28
28
|
from pathlib import Path
|
|
29
|
-
from typing import Any, Optional
|
|
29
|
+
from typing import Any, Optional
|
|
30
30
|
|
|
31
31
|
from ..archive.base import AArchiveFile
|
|
32
32
|
from ..contracts import IArchiveFile, IArchiver
|
|
@@ -63,7 +63,7 @@ class ZipFile(AArchiveFile):
|
|
|
63
63
|
>>> files = zip_file.list_contents()
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
-
def __init__(self, path:
|
|
66
|
+
def __init__(self, path: str | Path):
|
|
67
67
|
"""Initialize zip archive file."""
|
|
68
68
|
super().__init__(path, archiver=ZipArchiver())
|
|
69
69
|
self._archiver = ZipArchiver() # Composition!
|
|
@@ -150,7 +150,7 @@ class TarFile(AArchiveFile):
|
|
|
150
150
|
Supports compression: gzip, bz2, xz
|
|
151
151
|
"""
|
|
152
152
|
|
|
153
|
-
def __init__(self, path:
|
|
153
|
+
def __init__(self, path: str | Path, compression: str = ''):
|
|
154
154
|
"""
|
|
155
155
|
Initialize tar archive file.
|
|
156
156
|
|
|
@@ -215,6 +215,3 @@ class TarFile(AArchiveFile):
|
|
|
215
215
|
def get_archiver(self) -> IArchiver:
|
|
216
216
|
"""Get the underlying archiver codec."""
|
|
217
217
|
return self._archiver
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Archive codecs - In-memory archive processors.
|
|
@@ -22,11 +22,12 @@ Priority 4 (Performance): Efficient in-memory operations
|
|
|
22
22
|
Priority 5 (Extensibility): Easy to add new formats (7z, RAR, etc.)
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import sys
|
|
25
26
|
import zipfile
|
|
26
27
|
import tarfile
|
|
27
28
|
import io
|
|
28
29
|
from pathlib import Path
|
|
29
|
-
from typing import Any, Optional
|
|
30
|
+
from typing import Any, Optional
|
|
30
31
|
|
|
31
32
|
from ..archive.base import AArchiver
|
|
32
33
|
from ..contracts import IArchiver, EncodeOptions, DecodeOptions
|
|
@@ -96,6 +97,44 @@ class ZipArchiver(AArchiver):
|
|
|
96
97
|
def supports_capability(self, capability: CodecCapability) -> bool:
|
|
97
98
|
"""Check capability support."""
|
|
98
99
|
return capability in (CodecCapability.BIDIRECTIONAL, CodecCapability.COMPRESSION)
|
|
100
|
+
|
|
101
|
+
# ----------------------------------------------------------------------
|
|
102
|
+
# File-based convenience API (used by archive facade + tests)
|
|
103
|
+
# ----------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def format_id(self) -> str:
|
|
107
|
+
"""Format identifier alias (compat with archive facade/tests)."""
|
|
108
|
+
return self.codec_id
|
|
109
|
+
|
|
110
|
+
def create(self, files: list[Path], archive_path: Path, compression: int = zipfile.ZIP_DEFLATED) -> Path:
|
|
111
|
+
"""
|
|
112
|
+
Create a ZIP archive on disk from a list of files.
|
|
113
|
+
"""
|
|
114
|
+
try:
|
|
115
|
+
archive_path.parent.mkdir(parents=True, exist_ok=True)
|
|
116
|
+
with zipfile.ZipFile(archive_path, "w", compression=compression) as zf:
|
|
117
|
+
for file_path in files:
|
|
118
|
+
zf.write(file_path, arcname=file_path.name)
|
|
119
|
+
return archive_path
|
|
120
|
+
except Exception as e:
|
|
121
|
+
raise ArchiveError(f"Failed to create zip archive '{archive_path}': {e}")
|
|
122
|
+
|
|
123
|
+
def list_contents(self, archive_path: Path) -> list[str]:
|
|
124
|
+
"""List contents of a ZIP archive on disk."""
|
|
125
|
+
try:
|
|
126
|
+
with zipfile.ZipFile(archive_path, "r") as zf:
|
|
127
|
+
return zf.namelist()
|
|
128
|
+
except Exception as e:
|
|
129
|
+
raise ArchiveError(f"Failed to list zip contents for '{archive_path}': {e}")
|
|
130
|
+
|
|
131
|
+
def add_file(self, archive_path: Path, file_path: Path, compression: int = zipfile.ZIP_DEFLATED) -> None:
|
|
132
|
+
"""Add a file to an existing ZIP archive."""
|
|
133
|
+
try:
|
|
134
|
+
with zipfile.ZipFile(archive_path, "a", compression=compression) as zf:
|
|
135
|
+
zf.write(file_path, arcname=file_path.name)
|
|
136
|
+
except Exception as e:
|
|
137
|
+
raise ArchiveError(f"Failed to add file to zip '{archive_path}': {e}")
|
|
99
138
|
|
|
100
139
|
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes:
|
|
101
140
|
"""
|
|
@@ -174,13 +213,26 @@ class ZipArchiver(AArchiver):
|
|
|
174
213
|
"""
|
|
175
214
|
return self.encode(data, options=options)
|
|
176
215
|
|
|
177
|
-
def extract(self,
|
|
216
|
+
def extract(self, source: bytes | Path, extract_dir: Optional[Path] = None, **options) -> Any:
|
|
178
217
|
"""
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
218
|
+
Extract ZIP from either in-memory bytes or a file path.
|
|
219
|
+
|
|
220
|
+
- If source is bytes: returns dict[str, bytes] via decode()
|
|
221
|
+
- If source is Path: extracts to extract_dir and returns list[Path]
|
|
182
222
|
"""
|
|
183
|
-
|
|
223
|
+
if isinstance(source, (bytes, bytearray)):
|
|
224
|
+
return self.decode(bytes(source), options=options)
|
|
225
|
+
|
|
226
|
+
if extract_dir is None:
|
|
227
|
+
raise ArchiveError("extract_dir is required when extracting from a file path")
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
extract_dir.mkdir(parents=True, exist_ok=True)
|
|
231
|
+
with zipfile.ZipFile(source, "r") as zf:
|
|
232
|
+
zf.extractall(extract_dir)
|
|
233
|
+
return [extract_dir / name for name in zf.namelist()]
|
|
234
|
+
except Exception as e:
|
|
235
|
+
raise ArchiveError(f"Failed to extract zip archive '{source}': {e}")
|
|
184
236
|
|
|
185
237
|
|
|
186
238
|
class TarArchiver(AArchiver):
|
|
@@ -226,6 +278,42 @@ class TarArchiver(AArchiver):
|
|
|
226
278
|
def supports_capability(self, capability: CodecCapability) -> bool:
|
|
227
279
|
"""Check capability support."""
|
|
228
280
|
return capability in (CodecCapability.BIDIRECTIONAL, CodecCapability.COMPRESSION)
|
|
281
|
+
|
|
282
|
+
# ----------------------------------------------------------------------
|
|
283
|
+
# File-based convenience API (used by archive facade + tests)
|
|
284
|
+
# ----------------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def format_id(self) -> str:
|
|
288
|
+
"""Format identifier alias (compat with archive facade/tests)."""
|
|
289
|
+
return self.codec_id
|
|
290
|
+
|
|
291
|
+
def create(self, files: list[Path], archive_path: Path, mode: str = "w") -> Path:
|
|
292
|
+
"""Create a TAR archive on disk from a list of files."""
|
|
293
|
+
try:
|
|
294
|
+
archive_path.parent.mkdir(parents=True, exist_ok=True)
|
|
295
|
+
with tarfile.open(archive_path, mode) as tf:
|
|
296
|
+
for file_path in files:
|
|
297
|
+
tf.add(file_path, arcname=file_path.name)
|
|
298
|
+
return archive_path
|
|
299
|
+
except Exception as e:
|
|
300
|
+
raise ArchiveError(f"Failed to create tar archive '{archive_path}': {e}")
|
|
301
|
+
|
|
302
|
+
def list_contents(self, archive_path: Path) -> list[str]:
|
|
303
|
+
"""List contents of a TAR archive on disk."""
|
|
304
|
+
try:
|
|
305
|
+
with tarfile.open(archive_path, "r:*") as tf:
|
|
306
|
+
return [m.name for m in tf.getmembers() if m.name]
|
|
307
|
+
except Exception as e:
|
|
308
|
+
raise ArchiveError(f"Failed to list tar contents for '{archive_path}': {e}")
|
|
309
|
+
|
|
310
|
+
def add_file(self, archive_path: Path, file_path: Path) -> None:
|
|
311
|
+
"""Add a file to an existing TAR archive (append mode)."""
|
|
312
|
+
try:
|
|
313
|
+
with tarfile.open(archive_path, "a") as tf:
|
|
314
|
+
tf.add(file_path, arcname=file_path.name)
|
|
315
|
+
except Exception as e:
|
|
316
|
+
raise ArchiveError(f"Failed to add file to tar '{archive_path}': {e}")
|
|
229
317
|
|
|
230
318
|
def encode(self, value: Any, *, options: Optional[EncodeOptions] = None) -> bytes:
|
|
231
319
|
"""Encode data to tar bytes (in RAM)."""
|
|
@@ -286,7 +374,29 @@ class TarArchiver(AArchiver):
|
|
|
286
374
|
"""User-friendly: Compress data to tar bytes."""
|
|
287
375
|
return self.encode(data, options=options)
|
|
288
376
|
|
|
289
|
-
def extract(self,
|
|
290
|
-
"""
|
|
291
|
-
|
|
377
|
+
def extract(self, source: bytes | Path, extract_dir: Optional[Path] = None, **options) -> Any:
|
|
378
|
+
"""
|
|
379
|
+
Extract TAR from either in-memory bytes or a file path.
|
|
292
380
|
|
|
381
|
+
- If source is bytes: returns dict[str, bytes] via decode()
|
|
382
|
+
- If source is Path: extracts to extract_dir and returns list[Path]
|
|
383
|
+
"""
|
|
384
|
+
if isinstance(source, (bytes, bytearray)):
|
|
385
|
+
return self.decode(bytes(source), options=options)
|
|
386
|
+
|
|
387
|
+
if extract_dir is None:
|
|
388
|
+
raise ArchiveError("extract_dir is required when extracting from a file path")
|
|
389
|
+
|
|
390
|
+
try:
|
|
391
|
+
extract_dir.mkdir(parents=True, exist_ok=True)
|
|
392
|
+
with tarfile.open(source, "r:*") as tf:
|
|
393
|
+
# Use data filter for Python 3.12+ compatibility (prevents deprecation warning)
|
|
394
|
+
# data_filter allows all files but validates paths for security
|
|
395
|
+
# For older Python versions, filter parameter is not available
|
|
396
|
+
extract_kwargs = {}
|
|
397
|
+
if sys.version_info >= (3, 12):
|
|
398
|
+
extract_kwargs['filter'] = 'data'
|
|
399
|
+
tf.extractall(extract_dir, **extract_kwargs)
|
|
400
|
+
return [extract_dir / m.name for m in tf.getmembers() if m.name]
|
|
401
|
+
except Exception as e:
|
|
402
|
+
raise ArchiveError(f"Failed to extract tar archive '{source}': {e}")
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Base classes and registries for archive system.
|
|
@@ -19,7 +19,7 @@ Priority 5 (Extensibility): Easy to add 7z, RAR, etc.
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
from abc import ABC, abstractmethod
|
|
22
|
-
from typing import Optional,
|
|
22
|
+
from typing import Optional, Any
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
|
|
25
25
|
from ..contracts import IArchiveFormat, ICompressor, IArchiveMetadata, IArchiver, IArchiveFile, EncodeOptions, DecodeOptions
|
|
@@ -193,7 +193,7 @@ class AArchiveFile(AFile, IArchiveFile, ABC):
|
|
|
193
193
|
This is for file-based archive operations - works on archive files on disk.
|
|
194
194
|
"""
|
|
195
195
|
|
|
196
|
-
def __init__(self, file_path:
|
|
196
|
+
def __init__(self, file_path: str | Path, archiver: Optional[IArchiver] = None):
|
|
197
197
|
"""
|
|
198
198
|
Initialize archive file.
|
|
199
199
|
|
|
@@ -282,7 +282,7 @@ class ArchiveFormatRegistry:
|
|
|
282
282
|
"""Get archiver by format ID."""
|
|
283
283
|
return self._instances.get(format_id)
|
|
284
284
|
|
|
285
|
-
def get_by_extension(self, path:
|
|
285
|
+
def get_by_extension(self, path: str | Path) -> Optional[IArchiveFormat]:
|
|
286
286
|
"""
|
|
287
287
|
Get archiver by file extension (AUTO-DETECTION!).
|
|
288
288
|
|
|
@@ -374,4 +374,3 @@ def get_global_compression_registry() -> CompressionRegistry:
|
|
|
374
374
|
_global_compression_registry = CompressionRegistry()
|
|
375
375
|
# Auto-register built-in compressors (will be done in compression/__init__.py)
|
|
376
376
|
return _global_compression_registry
|
|
377
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: November 1, 2025
|
|
9
9
|
|
|
10
10
|
Archive-Codec Integration - Register archivers with CodecRegistry.
|
|
@@ -55,4 +55,3 @@ def register_archivers_as_codecs():
|
|
|
55
55
|
|
|
56
56
|
# Auto-register on import
|
|
57
57
|
register_archivers_as_codecs()
|
|
58
|
-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Company: eXonware.com
|
|
5
5
|
Author: Eng. Muhammad AlShehri
|
|
6
6
|
Email: connect@exonware.com
|
|
7
|
-
Version: 0.1.0.
|
|
7
|
+
Version: 0.1.0.4
|
|
8
8
|
Generation Date: 30-Oct-2025
|
|
9
9
|
|
|
10
10
|
Compression operations for gzip, bz2, and lzma.
|
|
@@ -184,4 +184,3 @@ class Compression(ICompression):
|
|
|
184
184
|
output.write_bytes(decompressed)
|
|
185
185
|
|
|
186
186
|
return output
|
|
187
|
-
|