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,385 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/event_logger.py
|
|
3
|
+
#exonware/xwsystem/console/event_logger.py
|
|
4
|
+
"""
|
|
5
|
+
Company: eXonware.com
|
|
6
|
+
Author: Eng. Muhammad AlShehri
|
|
7
|
+
Email: connect@exonware.com
|
|
8
|
+
Version: 0.1.0.4
|
|
9
|
+
Generation Date: 2025-01-27
|
|
10
|
+
|
|
11
|
+
Console Event Logger implementation for structured logging.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import time
|
|
15
|
+
import threading
|
|
16
|
+
from typing import Optional, Any
|
|
17
|
+
from .base import AEventLogger
|
|
18
|
+
from .defs import LogLevel, ConsoleEventType, ConsoleEvent
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ConsoleEventLogger(AEventLogger):
|
|
22
|
+
"""
|
|
23
|
+
Console event logger for structured logging.
|
|
24
|
+
|
|
25
|
+
This logger generates structured events with consistent formatting.
|
|
26
|
+
All other loggers in xwsystem should reuse this for structured logging.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
logger = ConsoleEventLogger()
|
|
30
|
+
logger.log("App initialized", source="app.init")
|
|
31
|
+
logger.error("Failed to connect", source="api.client", data={"endpoint": "/api/users"})
|
|
32
|
+
events = logger.get_events() # Returns list of ConsoleEvent dicts
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# Default colors for each event type
|
|
36
|
+
DEFAULT_COLORS = {
|
|
37
|
+
'log': '#ffffff',
|
|
38
|
+
'info': '#4aa3ff',
|
|
39
|
+
'warn': '#ffb020',
|
|
40
|
+
'error': '#ff4d4f',
|
|
41
|
+
'debug': '#b38cff',
|
|
42
|
+
'trace': '#ff85c0',
|
|
43
|
+
'group': '#ffd666',
|
|
44
|
+
'groupCollapsed': '#ffd666',
|
|
45
|
+
'groupEnd': '#ffd666',
|
|
46
|
+
'table': '#40a9ff',
|
|
47
|
+
'success': '#2ecc71',
|
|
48
|
+
'system': '#888',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Default labels for each event type
|
|
52
|
+
DEFAULT_LABELS = {
|
|
53
|
+
'log': 'LOG',
|
|
54
|
+
'info': 'INFO',
|
|
55
|
+
'warn': 'WARN',
|
|
56
|
+
'error': 'ERROR',
|
|
57
|
+
'debug': 'DEBUG',
|
|
58
|
+
'trace': 'TRACE',
|
|
59
|
+
'group': 'GROUP',
|
|
60
|
+
'groupCollapsed': 'GROUP',
|
|
61
|
+
'groupEnd': 'END',
|
|
62
|
+
'table': 'TABLE',
|
|
63
|
+
'success': 'OK',
|
|
64
|
+
'system': 'SYSTEM',
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Type to level mapping (when level not explicitly provided)
|
|
68
|
+
TYPE_TO_LEVEL: dict[ConsoleEventType, LogLevel] = {
|
|
69
|
+
'error': 'error',
|
|
70
|
+
'warn': 'warn',
|
|
71
|
+
'info': 'info',
|
|
72
|
+
'debug': 'debug',
|
|
73
|
+
'trace': 'debug',
|
|
74
|
+
'log': 'log',
|
|
75
|
+
'success': 'log',
|
|
76
|
+
'system': 'log',
|
|
77
|
+
'table': 'log',
|
|
78
|
+
'group': 'log',
|
|
79
|
+
'groupCollapsed': 'log',
|
|
80
|
+
'groupEnd': 'log',
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
max_entries: int = 1000,
|
|
86
|
+
use_milliseconds: bool = True,
|
|
87
|
+
default_source: Optional[str] = None
|
|
88
|
+
):
|
|
89
|
+
"""
|
|
90
|
+
Initialize console event logger.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
max_entries: Maximum number of events to keep in memory
|
|
94
|
+
use_milliseconds: If True, timestamps in milliseconds; if False, in seconds
|
|
95
|
+
default_source: Default source name for all events (can be overridden per event)
|
|
96
|
+
"""
|
|
97
|
+
self.max_entries = max_entries
|
|
98
|
+
self.use_milliseconds = use_milliseconds
|
|
99
|
+
self.default_source = default_source
|
|
100
|
+
self._events: list[ConsoleEvent] = []
|
|
101
|
+
self._event_id_counter = 0
|
|
102
|
+
self._lock = threading.Lock()
|
|
103
|
+
|
|
104
|
+
def _get_timestamp(self) -> float:
|
|
105
|
+
"""Get current timestamp in the configured format."""
|
|
106
|
+
if self.use_milliseconds:
|
|
107
|
+
return time.time() * 1000 # Milliseconds
|
|
108
|
+
return time.time() # Seconds
|
|
109
|
+
|
|
110
|
+
def _get_next_id(self) -> int:
|
|
111
|
+
"""Get next event ID (thread-safe)."""
|
|
112
|
+
with self._lock:
|
|
113
|
+
self._event_id_counter += 1
|
|
114
|
+
return self._event_id_counter
|
|
115
|
+
|
|
116
|
+
def _add_event(
|
|
117
|
+
self,
|
|
118
|
+
event_type: ConsoleEventType,
|
|
119
|
+
msg: str,
|
|
120
|
+
source: Optional[str] = None,
|
|
121
|
+
level: Optional[LogLevel] = None,
|
|
122
|
+
color: Optional[str] = None,
|
|
123
|
+
label: Optional[str] = None,
|
|
124
|
+
timestamp: Optional[float | int | str] = None,
|
|
125
|
+
data: Optional[Any] = None
|
|
126
|
+
) -> ConsoleEvent:
|
|
127
|
+
"""
|
|
128
|
+
Add an event to the log (internal method).
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
event_type: Type of console event
|
|
132
|
+
msg: Message text
|
|
133
|
+
source: Source/operation/module name (uses default_source if not provided)
|
|
134
|
+
level: Explicit log level (derived from type if not provided)
|
|
135
|
+
color: Color for display (uses default for type if not provided)
|
|
136
|
+
label: Label for badge (uses default for type if not provided)
|
|
137
|
+
timestamp: Timestamp (uses current time if not provided)
|
|
138
|
+
data: Additional structured data
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Created ConsoleEvent
|
|
142
|
+
"""
|
|
143
|
+
event_id = self._get_next_id()
|
|
144
|
+
event_timestamp = timestamp if timestamp is not None else self._get_timestamp()
|
|
145
|
+
event_source = source if source is not None else self.default_source
|
|
146
|
+
event_level = level if level is not None else self.TYPE_TO_LEVEL.get(event_type, 'log')
|
|
147
|
+
event_color = color if color is not None else self.DEFAULT_COLORS.get(event_type, '#ffffff')
|
|
148
|
+
event_label = label if label is not None else self.DEFAULT_LABELS.get(event_type, 'LOG')
|
|
149
|
+
|
|
150
|
+
event = ConsoleEvent(
|
|
151
|
+
id=event_id,
|
|
152
|
+
type=event_type,
|
|
153
|
+
timestamp=event_timestamp,
|
|
154
|
+
color=event_color,
|
|
155
|
+
label=event_label,
|
|
156
|
+
msg=msg,
|
|
157
|
+
source=event_source,
|
|
158
|
+
level=event_level,
|
|
159
|
+
data=data
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
with self._lock:
|
|
163
|
+
self._events.append(event)
|
|
164
|
+
# Limit entries
|
|
165
|
+
if len(self._events) > self.max_entries:
|
|
166
|
+
self._events = self._events[-self.max_entries:]
|
|
167
|
+
|
|
168
|
+
return event
|
|
169
|
+
|
|
170
|
+
# Public API methods matching common logging patterns
|
|
171
|
+
|
|
172
|
+
def log(
|
|
173
|
+
self,
|
|
174
|
+
msg: str,
|
|
175
|
+
source: Optional[str] = None,
|
|
176
|
+
data: Optional[Any] = None,
|
|
177
|
+
color: Optional[str] = None,
|
|
178
|
+
label: Optional[str] = None
|
|
179
|
+
) -> ConsoleEvent:
|
|
180
|
+
"""Log a general message."""
|
|
181
|
+
return self._add_event('log', msg, source=source, data=data, color=color, label=label)
|
|
182
|
+
|
|
183
|
+
def info(
|
|
184
|
+
self,
|
|
185
|
+
msg: str,
|
|
186
|
+
source: Optional[str] = None,
|
|
187
|
+
data: Optional[Any] = None
|
|
188
|
+
) -> ConsoleEvent:
|
|
189
|
+
"""Log an info message."""
|
|
190
|
+
return self._add_event('info', msg, source=source, data=data)
|
|
191
|
+
|
|
192
|
+
def warn(
|
|
193
|
+
self,
|
|
194
|
+
msg: str,
|
|
195
|
+
source: Optional[str] = None,
|
|
196
|
+
data: Optional[Any] = None
|
|
197
|
+
) -> ConsoleEvent:
|
|
198
|
+
"""Log a warning message."""
|
|
199
|
+
return self._add_event('warn', msg, source=source, data=data)
|
|
200
|
+
|
|
201
|
+
def error(
|
|
202
|
+
self,
|
|
203
|
+
msg: str,
|
|
204
|
+
source: Optional[str] = None,
|
|
205
|
+
data: Optional[Any] = None,
|
|
206
|
+
stack: Optional[str] = None
|
|
207
|
+
) -> ConsoleEvent:
|
|
208
|
+
"""Log an error message."""
|
|
209
|
+
error_data = data
|
|
210
|
+
if stack is not None:
|
|
211
|
+
error_data = error_data or {}
|
|
212
|
+
if isinstance(error_data, dict):
|
|
213
|
+
error_data['stack'] = stack
|
|
214
|
+
return self._add_event('error', msg, source=source, data=error_data)
|
|
215
|
+
|
|
216
|
+
def debug(
|
|
217
|
+
self,
|
|
218
|
+
msg: str,
|
|
219
|
+
source: Optional[str] = None,
|
|
220
|
+
data: Optional[Any] = None
|
|
221
|
+
) -> ConsoleEvent:
|
|
222
|
+
"""Log a debug message."""
|
|
223
|
+
return self._add_event('debug', msg, source=source, data=data)
|
|
224
|
+
|
|
225
|
+
def trace(
|
|
226
|
+
self,
|
|
227
|
+
msg: str,
|
|
228
|
+
source: Optional[str] = None,
|
|
229
|
+
data: Optional[Any] = None
|
|
230
|
+
) -> ConsoleEvent:
|
|
231
|
+
"""Log a trace message."""
|
|
232
|
+
return self._add_event('trace', msg, source=source, data=data)
|
|
233
|
+
|
|
234
|
+
def success(
|
|
235
|
+
self,
|
|
236
|
+
msg: str,
|
|
237
|
+
source: Optional[str] = None,
|
|
238
|
+
data: Optional[Any] = None
|
|
239
|
+
) -> ConsoleEvent:
|
|
240
|
+
"""Log a success message."""
|
|
241
|
+
return self._add_event('success', msg, source=source, data=data)
|
|
242
|
+
|
|
243
|
+
def system(
|
|
244
|
+
self,
|
|
245
|
+
msg: str,
|
|
246
|
+
source: Optional[str] = None,
|
|
247
|
+
data: Optional[Any] = None
|
|
248
|
+
) -> ConsoleEvent:
|
|
249
|
+
"""Log a system message."""
|
|
250
|
+
return self._add_event('system', msg, source=source, data=data)
|
|
251
|
+
|
|
252
|
+
def group(
|
|
253
|
+
self,
|
|
254
|
+
msg: str,
|
|
255
|
+
source: Optional[str] = None,
|
|
256
|
+
data: Optional[Any] = None
|
|
257
|
+
) -> ConsoleEvent:
|
|
258
|
+
"""Start a log group."""
|
|
259
|
+
return self._add_event('group', msg, source=source, data=data)
|
|
260
|
+
|
|
261
|
+
def group_collapsed(
|
|
262
|
+
self,
|
|
263
|
+
msg: str,
|
|
264
|
+
source: Optional[str] = None,
|
|
265
|
+
data: Optional[Any] = None
|
|
266
|
+
) -> ConsoleEvent:
|
|
267
|
+
"""Start a collapsed log group."""
|
|
268
|
+
return self._add_event('groupCollapsed', msg, source=source, data=data)
|
|
269
|
+
|
|
270
|
+
def group_end(
|
|
271
|
+
self,
|
|
272
|
+
msg: str = "",
|
|
273
|
+
source: Optional[str] = None
|
|
274
|
+
) -> ConsoleEvent:
|
|
275
|
+
"""End a log group."""
|
|
276
|
+
return self._add_event('groupEnd', msg, source=source)
|
|
277
|
+
|
|
278
|
+
def table(
|
|
279
|
+
self,
|
|
280
|
+
msg: str,
|
|
281
|
+
source: Optional[str] = None,
|
|
282
|
+
data: Optional[Any] = None
|
|
283
|
+
) -> ConsoleEvent:
|
|
284
|
+
"""Log a table message."""
|
|
285
|
+
return self._add_event('table', msg, source=source, data=data)
|
|
286
|
+
|
|
287
|
+
def add_event(
|
|
288
|
+
self,
|
|
289
|
+
event_type: ConsoleEventType,
|
|
290
|
+
msg: str,
|
|
291
|
+
source: Optional[str] = None,
|
|
292
|
+
level: Optional[LogLevel] = None,
|
|
293
|
+
color: Optional[str] = None,
|
|
294
|
+
label: Optional[str] = None,
|
|
295
|
+
timestamp: Optional[float | int | str] = None,
|
|
296
|
+
data: Optional[Any] = None
|
|
297
|
+
) -> ConsoleEvent:
|
|
298
|
+
"""
|
|
299
|
+
Add a custom event with full control over all fields.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
event_type: Type of console event
|
|
303
|
+
msg: Message text
|
|
304
|
+
source: Source/operation/module name
|
|
305
|
+
level: Explicit log level
|
|
306
|
+
color: Color for display
|
|
307
|
+
label: Label for badge
|
|
308
|
+
timestamp: Timestamp (Unix timestamp or ISO string)
|
|
309
|
+
data: Additional structured data
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
Created ConsoleEvent
|
|
313
|
+
"""
|
|
314
|
+
return self._add_event(
|
|
315
|
+
event_type, msg,
|
|
316
|
+
source=source,
|
|
317
|
+
level=level,
|
|
318
|
+
color=color,
|
|
319
|
+
label=label,
|
|
320
|
+
timestamp=timestamp,
|
|
321
|
+
data=data
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
def get_events(
|
|
325
|
+
self,
|
|
326
|
+
event_type: Optional[ConsoleEventType] = None,
|
|
327
|
+
level: Optional[LogLevel] = None,
|
|
328
|
+
source: Optional[str] = None,
|
|
329
|
+
limit: Optional[int] = None
|
|
330
|
+
) -> list[dict]:
|
|
331
|
+
"""
|
|
332
|
+
Get logged events as dictionaries.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
event_type: Filter by event type
|
|
336
|
+
level: Filter by log level
|
|
337
|
+
source: Filter by source
|
|
338
|
+
limit: Maximum number of events to return (most recent)
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
List of event dictionaries in ConsoleEvent format
|
|
342
|
+
"""
|
|
343
|
+
with self._lock:
|
|
344
|
+
events = self._events.copy()
|
|
345
|
+
|
|
346
|
+
# Apply filters
|
|
347
|
+
if event_type is not None:
|
|
348
|
+
events = [e for e in events if e.type == event_type]
|
|
349
|
+
if level is not None:
|
|
350
|
+
events = [e for e in events if (e.level or self.TYPE_TO_LEVEL.get(e.type, 'log')) == level]
|
|
351
|
+
if source is not None:
|
|
352
|
+
events = [e for e in events if e.source == source]
|
|
353
|
+
|
|
354
|
+
# Apply limit (most recent)
|
|
355
|
+
if limit is not None and limit > 0:
|
|
356
|
+
events = events[-limit:]
|
|
357
|
+
|
|
358
|
+
# Convert to dictionaries
|
|
359
|
+
return [e.to_dict() for e in events]
|
|
360
|
+
|
|
361
|
+
def get_events_raw(self) -> list[ConsoleEvent]:
|
|
362
|
+
"""
|
|
363
|
+
Get logged events as ConsoleEvent objects.
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
List of ConsoleEvent objects
|
|
367
|
+
"""
|
|
368
|
+
with self._lock:
|
|
369
|
+
return self._events.copy()
|
|
370
|
+
|
|
371
|
+
def clear(self) -> None:
|
|
372
|
+
"""Clear all logged events."""
|
|
373
|
+
with self._lock:
|
|
374
|
+
self._events.clear()
|
|
375
|
+
self._event_id_counter = 0
|
|
376
|
+
|
|
377
|
+
def count(self) -> int:
|
|
378
|
+
"""Get the number of logged events."""
|
|
379
|
+
with self._lock:
|
|
380
|
+
return len(self._events)
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
__all__ = [
|
|
384
|
+
'ConsoleEventLogger',
|
|
385
|
+
]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/writer.py
|
|
3
|
+
#exonware/xwsystem/console/writer.py
|
|
4
|
+
"""
|
|
5
|
+
Company: eXonware.com
|
|
6
|
+
Author: Eng. Muhammad AlShehri
|
|
7
|
+
Email: connect@exonware.com
|
|
8
|
+
Version: 0.1.0.4
|
|
9
|
+
Generation Date: 2025-01-27
|
|
10
|
+
|
|
11
|
+
Console Writer implementation for user interaction (not logging).
|
|
12
|
+
Can be used as a base class for bots and other user interaction systems.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import platform
|
|
17
|
+
import sys
|
|
18
|
+
from typing import Optional
|
|
19
|
+
from .base import AConsoleWriter
|
|
20
|
+
from .errors import ConsoleWriterError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConsoleWriter(AConsoleWriter):
|
|
24
|
+
"""
|
|
25
|
+
Console writer for user interaction (not logging).
|
|
26
|
+
|
|
27
|
+
This class provides methods for writing to and reading from the console.
|
|
28
|
+
Can be used as a base class for bots and other user interaction systems.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
writer = ConsoleWriter()
|
|
32
|
+
writer.write_line("Hello, user!")
|
|
33
|
+
name = writer.read("Enter your name: ")
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self):
|
|
37
|
+
"""Initialize console writer."""
|
|
38
|
+
self._supports_color = self._check_color_support()
|
|
39
|
+
self._is_interactive = self._check_interactive()
|
|
40
|
+
|
|
41
|
+
def _check_color_support(self) -> bool:
|
|
42
|
+
"""Check if terminal supports color."""
|
|
43
|
+
try:
|
|
44
|
+
return (
|
|
45
|
+
hasattr(sys.stdout, 'isatty') and
|
|
46
|
+
sys.stdout.isatty() and
|
|
47
|
+
os.getenv('TERM') != 'dumb' and
|
|
48
|
+
os.getenv('NO_COLOR') is None
|
|
49
|
+
)
|
|
50
|
+
except (AttributeError, OSError, RuntimeError):
|
|
51
|
+
# Catch specific exceptions - stdout may not support isatty
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
def _check_interactive(self) -> bool:
|
|
55
|
+
"""Check if console is interactive."""
|
|
56
|
+
try:
|
|
57
|
+
return hasattr(sys.stdin, 'isatty') and sys.stdin.isatty()
|
|
58
|
+
except (AttributeError, OSError, RuntimeError):
|
|
59
|
+
# Catch specific exceptions - stdin may not support isatty
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
def write(self, text: str, **kwargs) -> None:
|
|
63
|
+
"""
|
|
64
|
+
Write text to console.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
text: Text to write
|
|
68
|
+
**kwargs: Additional arguments passed to print()
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
print(text, end='', **kwargs)
|
|
72
|
+
sys.stdout.flush()
|
|
73
|
+
except Exception as e:
|
|
74
|
+
raise ConsoleWriterError(f"Failed to write to console: {e}")
|
|
75
|
+
|
|
76
|
+
def write_line(self, text: str = "", **kwargs) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Write a line to console.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
text: Text to write (default: empty string)
|
|
82
|
+
**kwargs: Additional arguments passed to print()
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
print(text, **kwargs)
|
|
86
|
+
sys.stdout.flush()
|
|
87
|
+
except Exception as e:
|
|
88
|
+
raise ConsoleWriterError(f"Failed to write line to console: {e}")
|
|
89
|
+
|
|
90
|
+
def read(self, prompt: str = "") -> str:
|
|
91
|
+
"""
|
|
92
|
+
Read input from console.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
prompt: Prompt text to display before reading
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
User input string
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
ConsoleWriterError: If console is not interactive
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
if not self._is_interactive:
|
|
105
|
+
raise ConsoleWriterError("Console is not interactive")
|
|
106
|
+
|
|
107
|
+
return input(prompt)
|
|
108
|
+
except Exception as e:
|
|
109
|
+
raise ConsoleWriterError(f"Failed to read from console: {e}")
|
|
110
|
+
|
|
111
|
+
def clear(self) -> None:
|
|
112
|
+
"""Clear console screen using Python's native platform detection."""
|
|
113
|
+
try:
|
|
114
|
+
if platform.system() == 'Windows':
|
|
115
|
+
os.system('cls')
|
|
116
|
+
else: # Unix/Linux/macOS
|
|
117
|
+
os.system('clear')
|
|
118
|
+
except Exception as e:
|
|
119
|
+
raise ConsoleWriterError(f"Failed to clear console: {e}")
|
|
120
|
+
|
|
121
|
+
def is_interactive(self) -> bool:
|
|
122
|
+
"""Check if console is interactive."""
|
|
123
|
+
return self._is_interactive
|
|
124
|
+
|
|
125
|
+
def supports_color(self) -> bool:
|
|
126
|
+
"""Check if console supports color."""
|
|
127
|
+
return self._supports_color
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
__all__ = [
|
|
131
|
+
'ConsoleWriter',
|
|
132
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/contracts.py
|
|
3
|
+
|
|
4
|
+
High-level, cross-cutting interfaces for xwsystem.
|
|
5
|
+
|
|
6
|
+
Company: eXonware.com
|
|
7
|
+
Author: Eng. Muhammad AlShehri
|
|
8
|
+
Email: connect@exonware.com
|
|
9
|
+
Version: 0.1.0.4
|
|
10
|
+
Last Updated: 29-Jan-2026
|
|
11
|
+
|
|
12
|
+
MANDATORY (GUIDE_31_DEV.md): interfaces in `contracts.py` MUST use `Protocol`.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Protocol, runtime_checkable
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@runtime_checkable
|
|
21
|
+
class IXWFacade(Protocol):
|
|
22
|
+
"""Marker interface for public xwsystem facades."""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"IXWFacade",
|
|
27
|
+
]
|
|
28
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/data_structures/__init__.py
|
|
3
|
+
|
|
4
|
+
Generic Data Structures for xwsystem.
|
|
5
|
+
|
|
6
|
+
Provides reusable data structures that can be used by any library:
|
|
7
|
+
- TrieNode: Internal node for Trie structures
|
|
8
|
+
- UnionFind: Union-Find (Disjoint Set) data structure
|
|
9
|
+
|
|
10
|
+
Company: eXonware.com
|
|
11
|
+
Author: Eng. Muhammad AlShehri
|
|
12
|
+
Email: connect@exonware.com
|
|
13
|
+
Version: 0.1.0.4
|
|
14
|
+
Generation Date: 26-Jan-2025
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .trie import TrieNode
|
|
18
|
+
from .union_find import UnionFind
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
'TrieNode',
|
|
22
|
+
'UnionFind',
|
|
23
|
+
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
#exonware/xwsystem/src/exonware/xwsystem/data_structures/trie.py
|
|
4
|
+
|
|
5
|
+
Trie Node for xwsystem.
|
|
6
|
+
|
|
7
|
+
Generic Trie node implementation that can be used by any library.
|
|
8
|
+
|
|
9
|
+
Company: eXonware.com
|
|
10
|
+
Author: Eng. Muhammad AlShehri
|
|
11
|
+
Email: connect@exonware.com
|
|
12
|
+
Version: 0.1.0.4
|
|
13
|
+
Generation Date: 26-Jan-2025
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from typing import Any, Dict
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TrieNode:
|
|
20
|
+
"""
|
|
21
|
+
Internal node for Trie structure.
|
|
22
|
+
|
|
23
|
+
Generic implementation that can be used by any library.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Initialize Trie node."""
|
|
28
|
+
self.children: Dict[str, TrieNode] = {}
|
|
29
|
+
self.is_end_word: bool = False
|
|
30
|
+
self.value: Any = None
|
|
31
|
+
|
|
32
|
+
def __repr__(self) -> str:
|
|
33
|
+
"""String representation of Trie node."""
|
|
34
|
+
return f"TrieNode(children={len(self.children)}, is_end={self.is_end_word})"
|