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.
Files changed (341) hide show
  1. exonware/__init__.py +2 -1
  2. exonware/conf.py +2 -2
  3. exonware/xwsystem/__init__.py +115 -43
  4. exonware/xwsystem/base.py +30 -0
  5. exonware/xwsystem/caching/__init__.py +39 -13
  6. exonware/xwsystem/caching/base.py +24 -6
  7. exonware/xwsystem/caching/bloom_cache.py +2 -2
  8. exonware/xwsystem/caching/cache_manager.py +2 -1
  9. exonware/xwsystem/caching/conditional.py +2 -2
  10. exonware/xwsystem/caching/contracts.py +85 -139
  11. exonware/xwsystem/caching/decorators.py +6 -19
  12. exonware/xwsystem/caching/defs.py +2 -1
  13. exonware/xwsystem/caching/disk_cache.py +2 -1
  14. exonware/xwsystem/caching/distributed.py +2 -1
  15. exonware/xwsystem/caching/errors.py +2 -1
  16. exonware/xwsystem/caching/events.py +110 -27
  17. exonware/xwsystem/caching/eviction_strategies.py +2 -2
  18. exonware/xwsystem/caching/external_caching_python.py +701 -0
  19. exonware/xwsystem/caching/facade.py +253 -0
  20. exonware/xwsystem/caching/factory.py +300 -0
  21. exonware/xwsystem/caching/fluent.py +14 -12
  22. exonware/xwsystem/caching/integrity.py +21 -6
  23. exonware/xwsystem/caching/lfu_cache.py +2 -1
  24. exonware/xwsystem/caching/lfu_optimized.py +18 -6
  25. exonware/xwsystem/caching/lru_cache.py +7 -4
  26. exonware/xwsystem/caching/memory_bounded.py +2 -2
  27. exonware/xwsystem/caching/metrics_exporter.py +2 -2
  28. exonware/xwsystem/caching/observable_cache.py +2 -2
  29. exonware/xwsystem/caching/pluggable_cache.py +2 -2
  30. exonware/xwsystem/caching/rate_limiter.py +2 -2
  31. exonware/xwsystem/caching/read_through.py +2 -2
  32. exonware/xwsystem/caching/secure_cache.py +81 -28
  33. exonware/xwsystem/caching/serializable.py +9 -7
  34. exonware/xwsystem/caching/stats.py +2 -2
  35. exonware/xwsystem/caching/tagging.py +2 -2
  36. exonware/xwsystem/caching/ttl_cache.py +4 -3
  37. exonware/xwsystem/caching/two_tier_cache.py +6 -3
  38. exonware/xwsystem/caching/utils.py +30 -12
  39. exonware/xwsystem/caching/validation.py +2 -2
  40. exonware/xwsystem/caching/warming.py +6 -3
  41. exonware/xwsystem/caching/write_behind.py +15 -6
  42. exonware/xwsystem/config/__init__.py +11 -17
  43. exonware/xwsystem/config/base.py +5 -5
  44. exonware/xwsystem/config/contracts.py +93 -153
  45. exonware/xwsystem/config/defaults.py +3 -2
  46. exonware/xwsystem/config/defs.py +3 -2
  47. exonware/xwsystem/config/errors.py +2 -5
  48. exonware/xwsystem/config/logging.py +12 -8
  49. exonware/xwsystem/config/logging_setup.py +3 -2
  50. exonware/xwsystem/config/performance.py +1 -46
  51. exonware/xwsystem/config/performance_modes.py +9 -8
  52. exonware/xwsystem/config/version_manager.py +1 -0
  53. exonware/xwsystem/config.py +27 -0
  54. exonware/xwsystem/console/__init__.py +53 -0
  55. exonware/xwsystem/console/base.py +133 -0
  56. exonware/xwsystem/console/cli/__init__.py +61 -0
  57. exonware/xwsystem/{cli → console/cli}/args.py +27 -24
  58. exonware/xwsystem/{cli → console/cli}/base.py +18 -87
  59. exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
  60. exonware/xwsystem/console/cli/console.py +98 -0
  61. exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
  62. exonware/xwsystem/console/cli/defs.py +87 -0
  63. exonware/xwsystem/console/cli/encoding.py +69 -0
  64. exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
  65. exonware/xwsystem/console/cli/event_logger.py +166 -0
  66. exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
  67. exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
  68. exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
  69. exonware/xwsystem/console/contracts.py +113 -0
  70. exonware/xwsystem/console/defs.py +154 -0
  71. exonware/xwsystem/console/errors.py +34 -0
  72. exonware/xwsystem/console/event_logger.py +385 -0
  73. exonware/xwsystem/console/writer.py +132 -0
  74. exonware/xwsystem/contracts.py +28 -0
  75. exonware/xwsystem/data_structures/__init__.py +23 -0
  76. exonware/xwsystem/data_structures/trie.py +34 -0
  77. exonware/xwsystem/data_structures/union_find.py +144 -0
  78. exonware/xwsystem/defs.py +17 -0
  79. exonware/xwsystem/errors.py +23 -0
  80. exonware/xwsystem/facade.py +62 -0
  81. exonware/xwsystem/http_client/__init__.py +22 -1
  82. exonware/xwsystem/http_client/advanced_client.py +8 -5
  83. exonware/xwsystem/http_client/base.py +3 -2
  84. exonware/xwsystem/http_client/client.py +7 -4
  85. exonware/xwsystem/http_client/contracts.py +42 -56
  86. exonware/xwsystem/http_client/defs.py +2 -1
  87. exonware/xwsystem/http_client/errors.py +2 -1
  88. exonware/xwsystem/http_client/facade.py +156 -0
  89. exonware/xwsystem/io/__init__.py +22 -3
  90. exonware/xwsystem/io/archive/__init__.py +8 -2
  91. exonware/xwsystem/io/archive/archive.py +1 -1
  92. exonware/xwsystem/io/archive/archive_files.py +4 -7
  93. exonware/xwsystem/io/archive/archivers.py +120 -10
  94. exonware/xwsystem/io/archive/base.py +4 -5
  95. exonware/xwsystem/io/archive/codec_integration.py +1 -2
  96. exonware/xwsystem/io/archive/compression.py +1 -2
  97. exonware/xwsystem/io/archive/facade.py +263 -0
  98. exonware/xwsystem/io/archive/formats/__init__.py +2 -3
  99. exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
  100. exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
  101. exonware/xwsystem/io/archive/formats/rar.py +11 -5
  102. exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
  103. exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
  104. exonware/xwsystem/io/archive/formats/tar.py +52 -7
  105. exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
  106. exonware/xwsystem/io/archive/formats/zip.py +1 -2
  107. exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
  108. exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
  109. exonware/xwsystem/io/base.py +119 -115
  110. exonware/xwsystem/io/codec/__init__.py +4 -2
  111. exonware/xwsystem/io/codec/base.py +19 -13
  112. exonware/xwsystem/io/codec/contracts.py +59 -2
  113. exonware/xwsystem/io/codec/registry.py +67 -21
  114. exonware/xwsystem/io/common/__init__.py +1 -1
  115. exonware/xwsystem/io/common/atomic.py +29 -16
  116. exonware/xwsystem/io/common/base.py +11 -10
  117. exonware/xwsystem/io/common/lock.py +6 -5
  118. exonware/xwsystem/io/common/path_manager.py +2 -1
  119. exonware/xwsystem/io/common/watcher.py +1 -2
  120. exonware/xwsystem/io/contracts.py +301 -433
  121. exonware/xwsystem/io/contracts_1.py +1180 -0
  122. exonware/xwsystem/io/data_operations.py +19 -20
  123. exonware/xwsystem/io/defs.py +4 -3
  124. exonware/xwsystem/io/errors.py +3 -2
  125. exonware/xwsystem/io/facade.py +87 -61
  126. exonware/xwsystem/io/file/__init__.py +1 -1
  127. exonware/xwsystem/io/file/base.py +8 -9
  128. exonware/xwsystem/io/file/conversion.py +2 -3
  129. exonware/xwsystem/io/file/file.py +61 -18
  130. exonware/xwsystem/io/file/paged_source.py +8 -8
  131. exonware/xwsystem/io/file/paging/__init__.py +1 -2
  132. exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
  133. exonware/xwsystem/io/file/paging/line_paging.py +2 -3
  134. exonware/xwsystem/io/file/paging/record_paging.py +2 -3
  135. exonware/xwsystem/io/file/paging/registry.py +1 -2
  136. exonware/xwsystem/io/file/source.py +13 -17
  137. exonware/xwsystem/io/filesystem/__init__.py +1 -1
  138. exonware/xwsystem/io/filesystem/base.py +1 -2
  139. exonware/xwsystem/io/filesystem/local.py +3 -4
  140. exonware/xwsystem/io/folder/__init__.py +1 -1
  141. exonware/xwsystem/io/folder/base.py +1 -2
  142. exonware/xwsystem/io/folder/folder.py +16 -7
  143. exonware/xwsystem/io/indexing/__init__.py +14 -0
  144. exonware/xwsystem/io/indexing/facade.py +443 -0
  145. exonware/xwsystem/io/path_parser.py +98 -0
  146. exonware/xwsystem/io/serialization/__init__.py +21 -3
  147. exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
  148. exonware/xwsystem/io/serialization/base.py +84 -34
  149. exonware/xwsystem/io/serialization/contracts.py +50 -73
  150. exonware/xwsystem/io/serialization/defs.py +2 -1
  151. exonware/xwsystem/io/serialization/errors.py +2 -1
  152. exonware/xwsystem/io/serialization/flyweight.py +154 -7
  153. exonware/xwsystem/io/serialization/format_detector.py +15 -14
  154. exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
  155. exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
  156. exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
  157. exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
  158. exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
  159. exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
  160. exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
  161. exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
  162. exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
  163. exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
  164. exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
  165. exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
  166. exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
  167. exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
  168. exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
  169. exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
  170. exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
  171. exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
  172. exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
  173. exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
  174. exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
  175. exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
  176. exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
  177. exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
  178. exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
  179. exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
  180. exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
  181. exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
  182. exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
  183. exonware/xwsystem/io/serialization/parsers/base.py +6 -5
  184. exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
  185. exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
  186. exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
  187. exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
  188. exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
  189. exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
  190. exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
  191. exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
  192. exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
  193. exonware/xwsystem/io/serialization/registry.py +4 -4
  194. exonware/xwsystem/io/serialization/serializer.py +168 -79
  195. exonware/xwsystem/io/serialization/universal_options.py +367 -0
  196. exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
  197. exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
  198. exonware/xwsystem/io/source_reader.py +223 -0
  199. exonware/xwsystem/io/stream/__init__.py +1 -1
  200. exonware/xwsystem/io/stream/async_operations.py +61 -14
  201. exonware/xwsystem/io/stream/base.py +1 -2
  202. exonware/xwsystem/io/stream/codec_io.py +6 -7
  203. exonware/xwsystem/ipc/__init__.py +1 -0
  204. exonware/xwsystem/ipc/async_fabric.py +4 -4
  205. exonware/xwsystem/ipc/base.py +6 -5
  206. exonware/xwsystem/ipc/contracts.py +41 -66
  207. exonware/xwsystem/ipc/defs.py +2 -1
  208. exonware/xwsystem/ipc/errors.py +2 -1
  209. exonware/xwsystem/ipc/message_queue.py +5 -2
  210. exonware/xwsystem/ipc/pipes.py +70 -34
  211. exonware/xwsystem/ipc/process_manager.py +7 -5
  212. exonware/xwsystem/ipc/process_pool.py +6 -5
  213. exonware/xwsystem/ipc/shared_memory.py +64 -11
  214. exonware/xwsystem/monitoring/__init__.py +7 -0
  215. exonware/xwsystem/monitoring/base.py +11 -8
  216. exonware/xwsystem/monitoring/contracts.py +86 -144
  217. exonware/xwsystem/monitoring/defs.py +2 -1
  218. exonware/xwsystem/monitoring/error_recovery.py +16 -3
  219. exonware/xwsystem/monitoring/errors.py +2 -1
  220. exonware/xwsystem/monitoring/facade.py +183 -0
  221. exonware/xwsystem/monitoring/memory_monitor.py +1 -0
  222. exonware/xwsystem/monitoring/metrics.py +1 -0
  223. exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
  224. exonware/xwsystem/monitoring/performance_monitor.py +1 -0
  225. exonware/xwsystem/monitoring/performance_validator.py +1 -0
  226. exonware/xwsystem/monitoring/system_monitor.py +6 -5
  227. exonware/xwsystem/monitoring/tracing.py +18 -16
  228. exonware/xwsystem/monitoring/tracker.py +2 -1
  229. exonware/xwsystem/operations/__init__.py +5 -50
  230. exonware/xwsystem/operations/base.py +3 -44
  231. exonware/xwsystem/operations/contracts.py +25 -15
  232. exonware/xwsystem/operations/defs.py +1 -1
  233. exonware/xwsystem/operations/diff.py +5 -4
  234. exonware/xwsystem/operations/errors.py +1 -1
  235. exonware/xwsystem/operations/merge.py +6 -4
  236. exonware/xwsystem/operations/patch.py +5 -4
  237. exonware/xwsystem/patterns/__init__.py +1 -0
  238. exonware/xwsystem/patterns/base.py +2 -1
  239. exonware/xwsystem/patterns/context_manager.py +2 -1
  240. exonware/xwsystem/patterns/contracts.py +215 -256
  241. exonware/xwsystem/patterns/defs.py +2 -1
  242. exonware/xwsystem/patterns/dynamic_facade.py +1 -0
  243. exonware/xwsystem/patterns/errors.py +2 -4
  244. exonware/xwsystem/patterns/handler_factory.py +2 -3
  245. exonware/xwsystem/patterns/import_registry.py +1 -0
  246. exonware/xwsystem/patterns/object_pool.py +1 -0
  247. exonware/xwsystem/patterns/registry.py +4 -43
  248. exonware/xwsystem/plugins/__init__.py +2 -1
  249. exonware/xwsystem/plugins/base.py +6 -5
  250. exonware/xwsystem/plugins/contracts.py +94 -158
  251. exonware/xwsystem/plugins/defs.py +2 -1
  252. exonware/xwsystem/plugins/errors.py +2 -1
  253. exonware/xwsystem/py.typed +3 -0
  254. exonware/xwsystem/query/__init__.py +36 -0
  255. exonware/xwsystem/query/contracts.py +56 -0
  256. exonware/xwsystem/query/errors.py +22 -0
  257. exonware/xwsystem/query/registry.py +128 -0
  258. exonware/xwsystem/runtime/__init__.py +2 -1
  259. exonware/xwsystem/runtime/base.py +4 -3
  260. exonware/xwsystem/runtime/contracts.py +39 -60
  261. exonware/xwsystem/runtime/defs.py +2 -1
  262. exonware/xwsystem/runtime/env.py +11 -9
  263. exonware/xwsystem/runtime/errors.py +2 -1
  264. exonware/xwsystem/runtime/reflection.py +3 -2
  265. exonware/xwsystem/security/__init__.py +68 -11
  266. exonware/xwsystem/security/audit.py +167 -0
  267. exonware/xwsystem/security/base.py +121 -24
  268. exonware/xwsystem/security/contracts.py +91 -146
  269. exonware/xwsystem/security/crypto.py +17 -16
  270. exonware/xwsystem/security/defs.py +2 -1
  271. exonware/xwsystem/security/errors.py +2 -1
  272. exonware/xwsystem/security/facade.py +321 -0
  273. exonware/xwsystem/security/file_security.py +330 -0
  274. exonware/xwsystem/security/hazmat.py +11 -8
  275. exonware/xwsystem/security/monitor.py +372 -0
  276. exonware/xwsystem/security/path_validator.py +140 -18
  277. exonware/xwsystem/security/policy.py +357 -0
  278. exonware/xwsystem/security/resource_limits.py +1 -0
  279. exonware/xwsystem/security/validator.py +455 -0
  280. exonware/xwsystem/shared/__init__.py +14 -1
  281. exonware/xwsystem/shared/base.py +285 -2
  282. exonware/xwsystem/shared/contracts.py +415 -126
  283. exonware/xwsystem/shared/defs.py +2 -1
  284. exonware/xwsystem/shared/errors.py +2 -2
  285. exonware/xwsystem/shared/xwobject.py +316 -0
  286. exonware/xwsystem/structures/__init__.py +1 -0
  287. exonware/xwsystem/structures/base.py +3 -2
  288. exonware/xwsystem/structures/circular_detector.py +15 -14
  289. exonware/xwsystem/structures/contracts.py +53 -76
  290. exonware/xwsystem/structures/defs.py +2 -1
  291. exonware/xwsystem/structures/errors.py +2 -1
  292. exonware/xwsystem/structures/tree_walker.py +2 -1
  293. exonware/xwsystem/threading/__init__.py +21 -4
  294. exonware/xwsystem/threading/async_primitives.py +6 -5
  295. exonware/xwsystem/threading/base.py +3 -2
  296. exonware/xwsystem/threading/contracts.py +87 -143
  297. exonware/xwsystem/threading/defs.py +2 -1
  298. exonware/xwsystem/threading/errors.py +2 -1
  299. exonware/xwsystem/threading/facade.py +175 -0
  300. exonware/xwsystem/threading/locks.py +1 -0
  301. exonware/xwsystem/threading/safe_factory.py +1 -0
  302. exonware/xwsystem/utils/__init__.py +40 -0
  303. exonware/xwsystem/utils/base.py +22 -21
  304. exonware/xwsystem/utils/contracts.py +50 -73
  305. exonware/xwsystem/utils/dt/__init__.py +19 -3
  306. exonware/xwsystem/utils/dt/base.py +5 -4
  307. exonware/xwsystem/utils/dt/contracts.py +22 -29
  308. exonware/xwsystem/utils/dt/defs.py +2 -1
  309. exonware/xwsystem/utils/dt/errors.py +2 -5
  310. exonware/xwsystem/utils/dt/formatting.py +88 -2
  311. exonware/xwsystem/utils/dt/humanize.py +10 -9
  312. exonware/xwsystem/utils/dt/parsing.py +56 -5
  313. exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
  314. exonware/xwsystem/utils/errors.py +2 -4
  315. exonware/xwsystem/utils/paths.py +1 -0
  316. exonware/xwsystem/utils/string.py +49 -0
  317. exonware/xwsystem/utils/test_runner.py +185 -0
  318. exonware/xwsystem/utils/utils_contracts.py +2 -1
  319. exonware/xwsystem/utils/web.py +110 -0
  320. exonware/xwsystem/validation/__init__.py +25 -1
  321. exonware/xwsystem/validation/base.py +6 -5
  322. exonware/xwsystem/validation/contracts.py +29 -41
  323. exonware/xwsystem/validation/data_validator.py +1 -0
  324. exonware/xwsystem/validation/declarative.py +11 -8
  325. exonware/xwsystem/validation/defs.py +2 -1
  326. exonware/xwsystem/validation/errors.py +2 -1
  327. exonware/xwsystem/validation/facade.py +198 -0
  328. exonware/xwsystem/validation/fluent_validator.py +22 -19
  329. exonware/xwsystem/validation/schema_discovery.py +210 -0
  330. exonware/xwsystem/validation/type_safety.py +2 -1
  331. exonware/xwsystem/version.py +2 -2
  332. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
  334. exonware/xwsystem/cli/__init__.py +0 -43
  335. exonware/xwsystem/cli/console.py +0 -113
  336. exonware/xwsystem/cli/defs.py +0 -134
  337. exonware/xwsystem/conf.py +0 -44
  338. exonware/xwsystem/security/auth.py +0 -484
  339. exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
  340. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
  341. {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})"