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
|
@@ -1,193 +1,175 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/cli/contracts.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: September 04, 2025
|
|
7
8
|
|
|
8
9
|
CLI module contracts - interfaces and enums for command-line interface functionality.
|
|
9
10
|
"""
|
|
10
11
|
|
|
11
|
-
from
|
|
12
|
-
from typing import Any, Optional
|
|
12
|
+
from typing import Protocol, runtime_checkable
|
|
13
|
+
from typing import Any, Optional
|
|
13
14
|
|
|
14
|
-
# Import enums from
|
|
15
|
+
# Import general console enums from console level (priority)
|
|
16
|
+
from ..defs import Alignment, BorderStyle, Colors, Style
|
|
17
|
+
# Import CLI-specific enums from defs
|
|
15
18
|
from .defs import (
|
|
16
19
|
ColorType,
|
|
17
20
|
ProgressStyle,
|
|
18
21
|
TableStyle,
|
|
19
22
|
PromptType,
|
|
20
|
-
Alignment,
|
|
21
|
-
BorderStyle,
|
|
22
|
-
Colors,
|
|
23
|
-
Style,
|
|
24
23
|
ArgumentType
|
|
25
24
|
)
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
@runtime_checkable
|
|
28
|
+
class IConsole(Protocol):
|
|
29
29
|
"""Interface for console operations."""
|
|
30
30
|
|
|
31
|
-
@abstractmethod
|
|
32
31
|
def print(self, text: str, color: Optional[ColorType] = None, **kwargs) -> None:
|
|
33
32
|
"""Print text to console."""
|
|
34
|
-
|
|
33
|
+
...
|
|
35
34
|
|
|
36
|
-
@abstractmethod
|
|
37
35
|
def input(self, prompt: str, **kwargs) -> str:
|
|
38
36
|
"""Get input from user."""
|
|
39
|
-
|
|
37
|
+
...
|
|
40
38
|
|
|
41
|
-
@abstractmethod
|
|
42
39
|
def clear(self) -> None:
|
|
43
40
|
"""Clear console screen."""
|
|
44
|
-
|
|
41
|
+
...
|
|
45
42
|
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
@runtime_checkable
|
|
45
|
+
class IProgressBar(Protocol):
|
|
48
46
|
"""Interface for progress bar operations."""
|
|
49
47
|
|
|
50
|
-
@abstractmethod
|
|
51
48
|
def start(self, total: int, description: str = "") -> None:
|
|
52
49
|
"""Start progress bar."""
|
|
53
|
-
|
|
50
|
+
...
|
|
54
51
|
|
|
55
|
-
@abstractmethod
|
|
56
52
|
def update(self, increment: int = 1) -> None:
|
|
57
53
|
"""Update progress."""
|
|
58
|
-
|
|
54
|
+
...
|
|
59
55
|
|
|
60
|
-
@abstractmethod
|
|
61
56
|
def finish(self) -> None:
|
|
62
57
|
"""Finish progress bar."""
|
|
63
|
-
|
|
58
|
+
...
|
|
64
59
|
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
@runtime_checkable
|
|
62
|
+
class ITable(Protocol):
|
|
67
63
|
"""Interface for table operations."""
|
|
68
64
|
|
|
69
|
-
@abstractmethod
|
|
70
65
|
def add_row(self, *values: Any) -> None:
|
|
71
66
|
"""Add row to table."""
|
|
72
|
-
|
|
67
|
+
...
|
|
73
68
|
|
|
74
|
-
@abstractmethod
|
|
75
69
|
def render(self) -> str:
|
|
76
70
|
"""Render table as string."""
|
|
77
|
-
|
|
71
|
+
...
|
|
78
72
|
|
|
79
73
|
|
|
80
|
-
|
|
74
|
+
@runtime_checkable
|
|
75
|
+
class IPrompt(Protocol):
|
|
81
76
|
"""Interface for user prompts."""
|
|
82
77
|
|
|
83
|
-
@abstractmethod
|
|
84
78
|
def ask(self, question: str, **kwargs) -> Any:
|
|
85
79
|
"""Ask user a question."""
|
|
86
|
-
|
|
80
|
+
...
|
|
87
81
|
|
|
88
82
|
|
|
89
|
-
|
|
83
|
+
@runtime_checkable
|
|
84
|
+
class IArgumentParser(Protocol):
|
|
90
85
|
"""Interface for argument parsing."""
|
|
91
86
|
|
|
92
|
-
@abstractmethod
|
|
93
87
|
def add_argument(self, *args, **kwargs) -> None:
|
|
94
88
|
"""Add argument to parser."""
|
|
95
|
-
|
|
89
|
+
...
|
|
96
90
|
|
|
97
|
-
@abstractmethod
|
|
98
91
|
def parse_args(self, args: Optional[list[str]] = None) -> Any:
|
|
99
92
|
"""Parse command line arguments."""
|
|
100
|
-
|
|
93
|
+
...
|
|
101
94
|
|
|
102
95
|
|
|
103
|
-
|
|
96
|
+
@runtime_checkable
|
|
97
|
+
class ICLI(Protocol):
|
|
104
98
|
"""Interface for CLI operations."""
|
|
105
99
|
|
|
106
100
|
@property
|
|
107
|
-
@abstractmethod
|
|
108
101
|
def name(self) -> str:
|
|
109
102
|
"""Get CLI name."""
|
|
110
|
-
|
|
103
|
+
...
|
|
111
104
|
|
|
112
105
|
@property
|
|
113
|
-
@abstractmethod
|
|
114
106
|
def version(self) -> str:
|
|
115
107
|
"""Get CLI version."""
|
|
116
|
-
|
|
108
|
+
...
|
|
117
109
|
|
|
118
|
-
@abstractmethod
|
|
119
110
|
def add_command(self, name: str, command: Any) -> None:
|
|
120
111
|
"""Add a command to the CLI."""
|
|
121
|
-
|
|
112
|
+
...
|
|
122
113
|
|
|
123
|
-
@abstractmethod
|
|
124
114
|
def add_option(self, name: str, option: Any) -> None:
|
|
125
115
|
"""Add an option to the CLI."""
|
|
126
|
-
|
|
116
|
+
...
|
|
127
117
|
|
|
128
|
-
@abstractmethod
|
|
129
118
|
def run(self, args: Optional[list[str]] = None) -> int:
|
|
130
119
|
"""Run the CLI."""
|
|
131
|
-
|
|
120
|
+
...
|
|
132
121
|
|
|
133
|
-
@abstractmethod
|
|
134
122
|
def get_help(self) -> str:
|
|
135
123
|
"""Get help text."""
|
|
136
|
-
|
|
124
|
+
...
|
|
137
125
|
|
|
138
126
|
|
|
139
|
-
|
|
127
|
+
@runtime_checkable
|
|
128
|
+
class IProgress(Protocol):
|
|
140
129
|
"""Interface for progress operations."""
|
|
141
130
|
|
|
142
|
-
@abstractmethod
|
|
143
131
|
def start(self, total: int, description: str = "") -> None:
|
|
144
132
|
"""Start progress tracking."""
|
|
145
|
-
|
|
133
|
+
...
|
|
146
134
|
|
|
147
|
-
@abstractmethod
|
|
148
135
|
def update(self, increment: int = 1) -> None:
|
|
149
136
|
"""Update progress."""
|
|
150
|
-
|
|
137
|
+
...
|
|
151
138
|
|
|
152
|
-
@abstractmethod
|
|
153
139
|
def finish(self) -> None:
|
|
154
140
|
"""Finish progress tracking."""
|
|
155
|
-
|
|
141
|
+
...
|
|
156
142
|
|
|
157
143
|
|
|
158
|
-
|
|
144
|
+
@runtime_checkable
|
|
145
|
+
class IPrompts(Protocol):
|
|
159
146
|
"""Interface for user prompts."""
|
|
160
147
|
|
|
161
|
-
@abstractmethod
|
|
162
148
|
def ask(self, question: str, **kwargs) -> Any:
|
|
163
149
|
"""Ask user a question."""
|
|
164
|
-
|
|
150
|
+
...
|
|
165
151
|
|
|
166
|
-
@abstractmethod
|
|
167
152
|
def confirm(self, message: str, default: bool = False) -> bool:
|
|
168
153
|
"""Ask for confirmation."""
|
|
169
|
-
|
|
154
|
+
...
|
|
170
155
|
|
|
171
|
-
@abstractmethod
|
|
172
156
|
def select(self, message: str, choices: list[str], default: Optional[str] = None) -> str:
|
|
173
157
|
"""Ask user to select from choices."""
|
|
174
|
-
|
|
158
|
+
...
|
|
175
159
|
|
|
176
160
|
|
|
177
|
-
|
|
161
|
+
@runtime_checkable
|
|
162
|
+
class ITableFormatter(Protocol):
|
|
178
163
|
"""Interface for table formatting."""
|
|
179
164
|
|
|
180
|
-
@abstractmethod
|
|
181
165
|
def add_row(self, *values: Any) -> None:
|
|
182
166
|
"""Add row to table."""
|
|
183
|
-
|
|
167
|
+
...
|
|
184
168
|
|
|
185
|
-
@abstractmethod
|
|
186
169
|
def render(self) -> str:
|
|
187
170
|
"""Render table as string."""
|
|
188
|
-
|
|
171
|
+
...
|
|
189
172
|
|
|
190
|
-
@abstractmethod
|
|
191
173
|
def clear(self) -> None:
|
|
192
174
|
"""Clear all rows."""
|
|
193
|
-
|
|
175
|
+
...
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/cli/defs.py
|
|
3
|
+
#exonware/xwsystem/console/cli/cli_defs.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: 07-Sep-2025
|
|
10
|
+
|
|
11
|
+
CLI-specific types and enums for XWSystem.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from enum import Enum
|
|
15
|
+
# Import general console enums from console level (priority)
|
|
16
|
+
from ..defs import Alignment, BorderStyle, Colors, Style
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ============================================================================
|
|
20
|
+
# CLI-SPECIFIC ENUMS
|
|
21
|
+
# ============================================================================
|
|
22
|
+
|
|
23
|
+
class ColorType(Enum):
|
|
24
|
+
"""Color types for CLI output."""
|
|
25
|
+
RESET = "reset"
|
|
26
|
+
BOLD = "bold"
|
|
27
|
+
DIM = "dim"
|
|
28
|
+
UNDERLINE = "underline"
|
|
29
|
+
RED = "red"
|
|
30
|
+
GREEN = "green"
|
|
31
|
+
YELLOW = "yellow"
|
|
32
|
+
BLUE = "blue"
|
|
33
|
+
MAGENTA = "magenta"
|
|
34
|
+
CYAN = "cyan"
|
|
35
|
+
WHITE = "white"
|
|
36
|
+
GRAY = "gray"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ProgressStyle(Enum):
|
|
40
|
+
"""Progress bar styles."""
|
|
41
|
+
BAR = "bar"
|
|
42
|
+
SPINNER = "spinner"
|
|
43
|
+
PERCENTAGE = "percentage"
|
|
44
|
+
COUNTER = "counter"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TableStyle(Enum):
|
|
48
|
+
"""Table display styles."""
|
|
49
|
+
SIMPLE = "simple"
|
|
50
|
+
GRID = "grid"
|
|
51
|
+
FANCY = "fancy"
|
|
52
|
+
MINIMAL = "minimal"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class PromptType(Enum):
|
|
56
|
+
"""Prompt input types."""
|
|
57
|
+
TEXT = "text"
|
|
58
|
+
PASSWORD = "password"
|
|
59
|
+
CONFIRM = "confirm"
|
|
60
|
+
SELECT = "select"
|
|
61
|
+
MULTISELECT = "multiselect"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ArgumentType(Enum):
|
|
65
|
+
"""Types of command-line arguments."""
|
|
66
|
+
STRING = "string"
|
|
67
|
+
INTEGER = "int"
|
|
68
|
+
FLOAT = "float"
|
|
69
|
+
BOOLEAN = "bool"
|
|
70
|
+
FILE = "file"
|
|
71
|
+
DIRECTORY = "dir"
|
|
72
|
+
CHOICE = "choice"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
__all__ = [
|
|
76
|
+
# Re-export general console enums
|
|
77
|
+
'Alignment',
|
|
78
|
+
'BorderStyle',
|
|
79
|
+
'Colors',
|
|
80
|
+
'Style',
|
|
81
|
+
# CLI-specific enums
|
|
82
|
+
'ColorType',
|
|
83
|
+
'ProgressStyle',
|
|
84
|
+
'TableStyle',
|
|
85
|
+
'PromptType',
|
|
86
|
+
'ArgumentType',
|
|
87
|
+
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/cli/encoding.py
|
|
3
|
+
"""
|
|
4
|
+
Console encoding utilities.
|
|
5
|
+
|
|
6
|
+
Best-effort UTF-8 configuration for Windows consoles (safe for uvicorn logging).
|
|
7
|
+
No-op on non-Windows platforms.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import io
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def ensure_utf8_console() -> None:
|
|
17
|
+
"""
|
|
18
|
+
Configure UTF-8 encoding for Windows console output streams.
|
|
19
|
+
|
|
20
|
+
- No-op on non-Windows platforms.
|
|
21
|
+
- Best-effort: never raises.
|
|
22
|
+
"""
|
|
23
|
+
if sys.platform != "win32":
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
# Prefer reconfigure when available (Python 3.7+)
|
|
28
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
29
|
+
try:
|
|
30
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
31
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
32
|
+
return
|
|
33
|
+
except (AttributeError, OSError):
|
|
34
|
+
# Fall back to wrapper below
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
class _UTF8Wrapper(io.TextIOWrapper):
|
|
38
|
+
"""Wrapper that delegates key methods to the original stream."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, buffer, **kwargs):
|
|
41
|
+
super().__init__(buffer, **kwargs)
|
|
42
|
+
self._original = buffer
|
|
43
|
+
|
|
44
|
+
def isatty(self):
|
|
45
|
+
return getattr(self._original, "isatty", lambda: False)()
|
|
46
|
+
|
|
47
|
+
def fileno(self):
|
|
48
|
+
return getattr(self._original, "fileno", lambda: -1)()
|
|
49
|
+
|
|
50
|
+
sys.stdout = _UTF8Wrapper(
|
|
51
|
+
sys.stdout.buffer,
|
|
52
|
+
encoding="utf-8",
|
|
53
|
+
errors="replace",
|
|
54
|
+
line_buffering=True,
|
|
55
|
+
)
|
|
56
|
+
sys.stderr = _UTF8Wrapper(
|
|
57
|
+
sys.stderr.buffer,
|
|
58
|
+
encoding="utf-8",
|
|
59
|
+
errors="replace",
|
|
60
|
+
line_buffering=True,
|
|
61
|
+
)
|
|
62
|
+
except Exception:
|
|
63
|
+
# Fallback on error
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
__all__ = [
|
|
68
|
+
"ensure_utf8_console",
|
|
69
|
+
]
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/cli/errors.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: September 04, 2025
|
|
7
8
|
|
|
8
9
|
CLI module errors - exception classes for command-line interface functionality.
|
|
9
10
|
"""
|
|
10
11
|
|
|
12
|
+
# Import base console errors from console level (priority)
|
|
13
|
+
from ..errors import ConsoleError as BaseConsoleError
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
class CLIError(Exception):
|
|
13
17
|
"""Base exception for CLI errors."""
|
|
@@ -24,8 +28,9 @@ class CommandError(CLIError):
|
|
|
24
28
|
pass
|
|
25
29
|
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
# ConsoleError extends base ConsoleError from console level
|
|
32
|
+
class ConsoleError(BaseConsoleError):
|
|
33
|
+
"""Raised when console operation fails (CLI-specific)."""
|
|
29
34
|
pass
|
|
30
35
|
|
|
31
36
|
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#exonware/xwsystem/src/exonware/xwsystem/console/cli/event_logger.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 2025
|
|
8
|
+
|
|
9
|
+
CLI Event Logger - Extends Python's logging.Logger with event logging capabilities.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Optional, Any
|
|
14
|
+
from ..event_logger import ConsoleEventLogger
|
|
15
|
+
from ..contracts import IEventLogger
|
|
16
|
+
from ..defs import LogLevel, ConsoleEventType, ConsoleEvent
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CliEventLogger(logging.Logger):
|
|
20
|
+
"""
|
|
21
|
+
CLI Event Logger that extends Python's logging.Logger.
|
|
22
|
+
|
|
23
|
+
Combines Python's standard logging.Logger with structured event logging
|
|
24
|
+
from ConsoleEventLogger. All standard logging.Logger methods work as expected,
|
|
25
|
+
and additional event logging methods are available.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, name: str, level: int = logging.NOTSET):
|
|
29
|
+
"""
|
|
30
|
+
Initialize CLI Event Logger.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
name: Logger name
|
|
34
|
+
level: Logging level
|
|
35
|
+
"""
|
|
36
|
+
# Initialize Python's Logger
|
|
37
|
+
super().__init__(name, level)
|
|
38
|
+
|
|
39
|
+
# Initialize internal event logger for structured logging
|
|
40
|
+
self._event_logger = ConsoleEventLogger(
|
|
41
|
+
max_entries=1000,
|
|
42
|
+
use_milliseconds=True,
|
|
43
|
+
default_source=name
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Event logging methods (from IEventLogger)
|
|
47
|
+
|
|
48
|
+
def log_event(
|
|
49
|
+
self,
|
|
50
|
+
msg: str,
|
|
51
|
+
source: Optional[str] = None,
|
|
52
|
+
data: Optional[Any] = None,
|
|
53
|
+
color: Optional[str] = None,
|
|
54
|
+
label: Optional[str] = None
|
|
55
|
+
) -> ConsoleEvent:
|
|
56
|
+
"""Log a general event message."""
|
|
57
|
+
event = self._event_logger.log(msg, source=source, data=data, color=color, label=label)
|
|
58
|
+
# Also log using standard logger
|
|
59
|
+
super().info(msg)
|
|
60
|
+
return event
|
|
61
|
+
|
|
62
|
+
def info_event(
|
|
63
|
+
self,
|
|
64
|
+
msg: str,
|
|
65
|
+
source: Optional[str] = None,
|
|
66
|
+
data: Optional[Any] = None
|
|
67
|
+
) -> ConsoleEvent:
|
|
68
|
+
"""Log an info event."""
|
|
69
|
+
event = self._event_logger.info(msg, source=source, data=data)
|
|
70
|
+
super().info(msg)
|
|
71
|
+
return event
|
|
72
|
+
|
|
73
|
+
def warn_event(
|
|
74
|
+
self,
|
|
75
|
+
msg: str,
|
|
76
|
+
source: Optional[str] = None,
|
|
77
|
+
data: Optional[Any] = None
|
|
78
|
+
) -> ConsoleEvent:
|
|
79
|
+
"""Log a warning event."""
|
|
80
|
+
event = self._event_logger.warn(msg, source=source, data=data)
|
|
81
|
+
super().warning(msg)
|
|
82
|
+
return event
|
|
83
|
+
|
|
84
|
+
def error_event(
|
|
85
|
+
self,
|
|
86
|
+
msg: str,
|
|
87
|
+
source: Optional[str] = None,
|
|
88
|
+
data: Optional[Any] = None,
|
|
89
|
+
stack: Optional[str] = None
|
|
90
|
+
) -> ConsoleEvent:
|
|
91
|
+
"""Log an error event."""
|
|
92
|
+
event = self._event_logger.error(msg, source=source, data=data, stack=stack)
|
|
93
|
+
super().error(msg, exc_info=stack is not None)
|
|
94
|
+
return event
|
|
95
|
+
|
|
96
|
+
def debug_event(
|
|
97
|
+
self,
|
|
98
|
+
msg: str,
|
|
99
|
+
source: Optional[str] = None,
|
|
100
|
+
data: Optional[Any] = None
|
|
101
|
+
) -> ConsoleEvent:
|
|
102
|
+
"""Log a debug event."""
|
|
103
|
+
event = self._event_logger.debug(msg, source=source, data=data)
|
|
104
|
+
super().debug(msg)
|
|
105
|
+
return event
|
|
106
|
+
|
|
107
|
+
# Override standard logging methods to also log events
|
|
108
|
+
def info(self, msg: object, *args, **kwargs) -> None:
|
|
109
|
+
"""Log info message (standard logger + event logger)."""
|
|
110
|
+
msg_str = str(msg) % args if args else str(msg)
|
|
111
|
+
self._event_logger.info(msg_str, source=self.name)
|
|
112
|
+
super().info(msg, *args, **kwargs)
|
|
113
|
+
|
|
114
|
+
def warning(self, msg: object, *args, **kwargs) -> None:
|
|
115
|
+
"""Log warning message (standard logger + event logger)."""
|
|
116
|
+
msg_str = str(msg) % args if args else str(msg)
|
|
117
|
+
self._event_logger.warn(msg_str, source=self.name)
|
|
118
|
+
super().warning(msg, *args, **kwargs)
|
|
119
|
+
|
|
120
|
+
def error(self, msg: object, *args, **kwargs) -> None:
|
|
121
|
+
"""Log error message (standard logger + event logger)."""
|
|
122
|
+
msg_str = str(msg) % args if args else str(msg)
|
|
123
|
+
self._event_logger.error(msg_str, source=self.name)
|
|
124
|
+
super().error(msg, *args, **kwargs)
|
|
125
|
+
|
|
126
|
+
def debug(self, msg: object, *args, **kwargs) -> None:
|
|
127
|
+
"""Log debug message (standard logger + event logger)."""
|
|
128
|
+
msg_str = str(msg) % args if args else str(msg)
|
|
129
|
+
self._event_logger.debug(msg_str, source=self.name)
|
|
130
|
+
super().debug(msg, *args, **kwargs)
|
|
131
|
+
|
|
132
|
+
def critical(self, msg: object, *args, **kwargs) -> None:
|
|
133
|
+
"""Log critical message (standard logger + event logger)."""
|
|
134
|
+
msg_str = str(msg) % args if args else str(msg)
|
|
135
|
+
self._event_logger.error(msg_str, source=self.name)
|
|
136
|
+
super().critical(msg, *args, **kwargs)
|
|
137
|
+
|
|
138
|
+
# Event logger methods (delegate to internal event logger)
|
|
139
|
+
|
|
140
|
+
def get_events(
|
|
141
|
+
self,
|
|
142
|
+
event_type: Optional[ConsoleEventType] = None,
|
|
143
|
+
level: Optional[LogLevel] = None,
|
|
144
|
+
source: Optional[str] = None,
|
|
145
|
+
limit: Optional[int] = None
|
|
146
|
+
) -> list[dict]:
|
|
147
|
+
"""Get logged events as dictionaries."""
|
|
148
|
+
return self._event_logger.get_events(event_type=event_type, level=level, source=source, limit=limit)
|
|
149
|
+
|
|
150
|
+
def clear_events(self) -> None:
|
|
151
|
+
"""Clear all logged events."""
|
|
152
|
+
self._event_logger.clear()
|
|
153
|
+
|
|
154
|
+
def count_events(self) -> int:
|
|
155
|
+
"""Get the number of logged events."""
|
|
156
|
+
return self._event_logger.count()
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def event_logger(self) -> ConsoleEventLogger:
|
|
160
|
+
"""Get the internal event logger instance."""
|
|
161
|
+
return self._event_logger
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
__all__ = [
|
|
165
|
+
'CliEventLogger',
|
|
166
|
+
]
|