exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.3__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.3.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.3.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.3.dist-info}/WHEEL +0 -0
  341. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env python3
2
- #exonware/xwsystem/cli/types.py
3
- """
4
- Company: eXonware.com
5
- Author: Eng. Muhammad AlShehri
6
- Email: connect@exonware.com
7
- Version: 0.1.0.1
8
- Generation Date: 07-Sep-2025
9
-
10
- CLI types and enums for XWSystem.
11
- """
12
-
13
- from enum import Enum
14
-
15
-
16
- # ============================================================================
17
- # CLI ENUMS
18
- # ============================================================================
19
-
20
- class ColorType(Enum):
21
- """Color types for CLI output."""
22
- RESET = "reset"
23
- BOLD = "bold"
24
- DIM = "dim"
25
- UNDERLINE = "underline"
26
- RED = "red"
27
- GREEN = "green"
28
- YELLOW = "yellow"
29
- BLUE = "blue"
30
- MAGENTA = "magenta"
31
- CYAN = "cyan"
32
- WHITE = "white"
33
- GRAY = "gray"
34
-
35
-
36
- class ProgressStyle(Enum):
37
- """Progress bar styles."""
38
- BAR = "bar"
39
- SPINNER = "spinner"
40
- PERCENTAGE = "percentage"
41
- COUNTER = "counter"
42
-
43
-
44
- class TableStyle(Enum):
45
- """Table display styles."""
46
- SIMPLE = "simple"
47
- GRID = "grid"
48
- FANCY = "fancy"
49
- MINIMAL = "minimal"
50
-
51
-
52
- class PromptType(Enum):
53
- """Prompt input types."""
54
- TEXT = "text"
55
- PASSWORD = "password"
56
- CONFIRM = "confirm"
57
- SELECT = "select"
58
- MULTISELECT = "multiselect"
59
-
60
-
61
- class Alignment(Enum):
62
- """Text alignment options."""
63
- LEFT = "left"
64
- CENTER = "center"
65
- RIGHT = "right"
66
-
67
-
68
- class BorderStyle(Enum):
69
- """Table border styles."""
70
- NONE = "none"
71
- ASCII = "ascii"
72
- SIMPLE = "simple"
73
- ROUNDED = "rounded"
74
- DOUBLE = "double"
75
- THICK = "thick"
76
-
77
-
78
- class Colors(Enum):
79
- """ANSI color codes."""
80
- # Standard colors
81
- BLACK = "\033[30m"
82
- RED = "\033[31m"
83
- GREEN = "\033[32m"
84
- YELLOW = "\033[33m"
85
- BLUE = "\033[34m"
86
- MAGENTA = "\033[35m"
87
- CYAN = "\033[36m"
88
- WHITE = "\033[37m"
89
-
90
- # Bright colors
91
- BRIGHT_BLACK = "\033[90m"
92
- BRIGHT_RED = "\033[91m"
93
- BRIGHT_GREEN = "\033[92m"
94
- BRIGHT_YELLOW = "\033[93m"
95
- BRIGHT_BLUE = "\033[94m"
96
- BRIGHT_MAGENTA = "\033[95m"
97
- BRIGHT_CYAN = "\033[96m"
98
- BRIGHT_WHITE = "\033[97m"
99
-
100
- # Background colors
101
- BG_BLACK = "\033[40m"
102
- BG_RED = "\033[41m"
103
- BG_GREEN = "\033[42m"
104
- BG_YELLOW = "\033[43m"
105
- BG_BLUE = "\033[44m"
106
- BG_MAGENTA = "\033[45m"
107
- BG_CYAN = "\033[46m"
108
- BG_WHITE = "\033[47m"
109
-
110
- # Reset
111
- RESET = "\033[0m"
112
-
113
-
114
- class Style(Enum):
115
- """ANSI style codes."""
116
- RESET = "\033[0m"
117
- BOLD = "\033[1m"
118
- DIM = "\033[2m"
119
- ITALIC = "\033[3m"
120
- UNDERLINE = "\033[4m"
121
- BLINK = "\033[5m"
122
- REVERSE = "\033[7m"
123
- STRIKETHROUGH = "\033[9m"
124
-
125
-
126
- class ArgumentType(Enum):
127
- """Types of command-line arguments."""
128
- STRING = "string"
129
- INTEGER = "int"
130
- FLOAT = "float"
131
- BOOLEAN = "bool"
132
- FILE = "file"
133
- DIRECTORY = "dir"
134
- CHOICE = "choice"
exonware/xwsystem/conf.py DELETED
@@ -1,44 +0,0 @@
1
- """
2
- Public-facing configuration shorthands.
3
-
4
- This module delegates to exonware.conf for backward compatibility.
5
- For new code, prefer: import exonware.conf as conf
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import sys
11
- import types
12
-
13
- # Delegate to top-level conf for backward compatibility
14
- # This allows both import patterns to work:
15
- # - import exonware.conf as conf (preferred - no xwsystem initialization)
16
- # - import exonware.xwsystem.conf as conf (backward compatible)
17
-
18
-
19
- class _ConfModule(types.ModuleType):
20
- """Expose selected config toggles as module-level attributes."""
21
-
22
- def __getattr__(self, name: str):
23
- # Delegate to top-level conf module
24
- try:
25
- import exonware.conf as top_conf
26
- return getattr(top_conf.xwsystem, name)
27
- except (ImportError, AttributeError):
28
- raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
29
-
30
- def __setattr__(self, name: str, value) -> None:
31
- if name.startswith('_'):
32
- super().__setattr__(name, value)
33
- return
34
-
35
- # Delegate to top-level conf module
36
- try:
37
- import exonware.conf as top_conf
38
- setattr(top_conf.xwsystem, name, value)
39
- except (ImportError, AttributeError):
40
- super().__setattr__(name, value)
41
-
42
-
43
- sys.modules[__name__].__class__ = _ConfModule
44
-
@@ -1,484 +0,0 @@
1
- """
2
- Company: eXonware.com
3
- Author: Eng. Muhammad AlShehri
4
- Email: connect@exonware.com
5
- Version: 0.1.0.1
6
- Generation Date: September 04, 2025
7
-
8
- Advanced Authentication Providers for Enterprise Integration
9
-
10
- Provides enterprise authentication mechanisms:
11
- - OAuth2 (Authorization Code, Client Credentials, Resource Owner)
12
- - JWT (JSON Web Tokens) with RS256/HS256
13
- - SAML 2.0 integration
14
- - Multi-factor authentication support
15
- - Token refresh and validation
16
- """
17
-
18
- import json
19
- import time
20
- import base64
21
- import hashlib
22
- import hmac
23
- from typing import Any, Optional, Union
24
- from urllib.parse import urlencode, parse_qs
25
- from .base import AAuthProvider, ATokenInfo, AUserInfo
26
- from .errors import AuthenticationError, AuthorizationError, TokenExpiredError
27
- from .defs import OAuth2GrantType
28
-
29
- from ..config.logging_setup import get_logger
30
-
31
- # Lazy imports to avoid import errors during test collection
32
- # These are only imported when actually needed
33
- def _get_jwt():
34
- """Lazy import jwt module."""
35
- try:
36
- import jwt
37
- return jwt
38
- except ImportError:
39
- raise ImportError(
40
- "PyJWT is required for JWT authentication. "
41
- "Install it with: pip install PyJWT"
42
- )
43
-
44
- def _get_requests():
45
- """Lazy import requests module."""
46
- try:
47
- import requests
48
- return requests
49
- except ImportError:
50
- raise ImportError(
51
- "requests is required for OAuth2 authentication. "
52
- "Install it with: pip install requests"
53
- )
54
-
55
- logger = get_logger("xwsystem.security.auth")
56
-
57
-
58
- class OAuth2Provider(AAuthProvider):
59
- """OAuth2 authentication provider."""
60
-
61
- def __init__(
62
- self,
63
- client_id: str,
64
- client_secret: str,
65
- authorization_url: str,
66
- token_url: str,
67
- userinfo_url: Optional[str] = None,
68
- scopes: Optional[list[str]] = None
69
- ):
70
- """
71
- Initialize OAuth2 provider.
72
-
73
- Args:
74
- client_id: OAuth2 client ID
75
- client_secret: OAuth2 client secret
76
- authorization_url: Authorization endpoint URL
77
- token_url: Token endpoint URL
78
- userinfo_url: Optional user info endpoint URL
79
- scopes: Optional list of scopes to request
80
- """
81
- # requests is now required
82
-
83
- self.client_id = client_id
84
- self.client_secret = client_secret
85
- self.authorization_url = authorization_url
86
- self.token_url = token_url
87
- self.userinfo_url = userinfo_url
88
- self.scopes = scopes or []
89
-
90
- def get_authorization_url(self, redirect_uri: str, state: Optional[str] = None) -> str:
91
- """Get authorization URL for OAuth2 flow."""
92
- params = {
93
- 'response_type': 'code',
94
- 'client_id': self.client_id,
95
- 'redirect_uri': redirect_uri,
96
- 'scope': ' '.join(self.scopes)
97
- }
98
-
99
- if state:
100
- params['state'] = state
101
-
102
- return f"{self.authorization_url}?{urlencode(params)}"
103
-
104
- async def authenticate(self, credentials: dict[str, Any]) -> ATokenInfo:
105
- """Authenticate using OAuth2 flow."""
106
- import asyncio
107
-
108
- def _authenticate():
109
- grant_type = credentials.get('grant_type', OAuth2GrantType.AUTHORIZATION_CODE.value)
110
-
111
- if grant_type == OAuth2GrantType.AUTHORIZATION_CODE.value:
112
- return self._authenticate_authorization_code(credentials)
113
- elif grant_type == OAuth2GrantType.CLIENT_CREDENTIALS.value:
114
- return self._authenticate_client_credentials()
115
- elif grant_type == OAuth2GrantType.RESOURCE_OWNER.value:
116
- return self._authenticate_resource_owner(credentials)
117
- else:
118
- raise AuthenticationError(f"Unsupported grant type: {grant_type}")
119
-
120
- return await asyncio.to_thread(_authenticate)
121
-
122
- def _authenticate_authorization_code(self, credentials: dict[str, Any]) -> ATokenInfo:
123
- """Authenticate using authorization code."""
124
- requests = _get_requests()
125
- data = {
126
- 'grant_type': OAuth2GrantType.AUTHORIZATION_CODE.value,
127
- 'client_id': self.client_id,
128
- 'client_secret': self.client_secret,
129
- 'code': credentials['code'],
130
- 'redirect_uri': credentials['redirect_uri']
131
- }
132
-
133
- response = requests.post(self.token_url, data=data)
134
-
135
- if response.status_code != 200:
136
- raise AuthenticationError(f"OAuth2 authentication failed: {response.text}")
137
-
138
- token_data = response.json()
139
- return ATokenInfo(
140
- access_token=token_data['access_token'],
141
- token_type=token_data.get('token_type', 'Bearer'),
142
- expires_in=token_data.get('expires_in'),
143
- refresh_token=token_data.get('refresh_token'),
144
- scope=token_data.get('scope')
145
- )
146
-
147
- def _authenticate_client_credentials(self) -> ATokenInfo:
148
- """Authenticate using client credentials."""
149
- requests = _get_requests()
150
- data = {
151
- 'grant_type': OAuth2GrantType.CLIENT_CREDENTIALS.value,
152
- 'client_id': self.client_id,
153
- 'client_secret': self.client_secret,
154
- 'scope': ' '.join(self.scopes)
155
- }
156
-
157
- response = requests.post(self.token_url, data=data)
158
-
159
- if response.status_code != 200:
160
- raise AuthenticationError(f"OAuth2 authentication failed: {response.text}")
161
-
162
- token_data = response.json()
163
- return ATokenInfo(
164
- access_token=token_data['access_token'],
165
- token_type=token_data.get('token_type', 'Bearer'),
166
- expires_in=token_data.get('expires_in'),
167
- scope=token_data.get('scope')
168
- )
169
-
170
- def _authenticate_resource_owner(self, credentials: dict[str, Any]) -> ATokenInfo:
171
- """Authenticate using resource owner credentials."""
172
- requests = _get_requests()
173
- data = {
174
- 'grant_type': OAuth2GrantType.RESOURCE_OWNER.value,
175
- 'client_id': self.client_id,
176
- 'client_secret': self.client_secret,
177
- 'username': credentials['username'],
178
- 'password': credentials['password'],
179
- 'scope': ' '.join(self.scopes)
180
- }
181
-
182
- response = requests.post(self.token_url, data=data)
183
-
184
- if response.status_code != 200:
185
- raise AuthenticationError(f"OAuth2 authentication failed: {response.text}")
186
-
187
- token_data = response.json()
188
- return ATokenInfo(
189
- access_token=token_data['access_token'],
190
- token_type=token_data.get('token_type', 'Bearer'),
191
- expires_in=token_data.get('expires_in'),
192
- refresh_token=token_data.get('refresh_token'),
193
- scope=token_data.get('scope')
194
- )
195
-
196
- async def validate_token(self, token: str) -> AUserInfo:
197
- """Validate OAuth2 token."""
198
- if not self.userinfo_url:
199
- raise AuthenticationError("User info URL not configured")
200
-
201
- import asyncio
202
-
203
- def _validate():
204
- requests = _get_requests()
205
- headers = {'Authorization': f'Bearer {token}'}
206
- response = requests.get(self.userinfo_url, headers=headers)
207
-
208
- if response.status_code == 401:
209
- raise TokenExpiredError("Token expired or invalid")
210
- elif response.status_code != 200:
211
- raise AuthenticationError(f"Token validation failed: {response.text}")
212
-
213
- user_data = response.json()
214
- return AUserInfo(
215
- user_id=user_data.get('sub', user_data.get('id', 'unknown')),
216
- username=user_data.get('preferred_username', user_data.get('username')),
217
- email=user_data.get('email'),
218
- attributes=user_data
219
- )
220
-
221
- return await asyncio.to_thread(_validate)
222
-
223
- async def refresh_token(self, refresh_token: str) -> ATokenInfo:
224
- """Refresh OAuth2 token."""
225
- import asyncio
226
-
227
- def _refresh():
228
- requests = _get_requests()
229
- data = {
230
- 'grant_type': OAuth2GrantType.REFRESH_TOKEN.value,
231
- 'client_id': self.client_id,
232
- 'client_secret': self.client_secret,
233
- 'refresh_token': refresh_token
234
- }
235
-
236
- response = requests.post(self.token_url, data=data)
237
-
238
- if response.status_code != 200:
239
- raise AuthenticationError(f"Token refresh failed: {response.text}")
240
-
241
- token_data = response.json()
242
- return ATokenInfo(
243
- access_token=token_data['access_token'],
244
- token_type=token_data.get('token_type', 'Bearer'),
245
- expires_in=token_data.get('expires_in'),
246
- refresh_token=token_data.get('refresh_token', refresh_token),
247
- scope=token_data.get('scope')
248
- )
249
-
250
- return await asyncio.to_thread(_refresh)
251
-
252
-
253
- class JWTProvider(AAuthProvider):
254
- """JWT (JSON Web Token) authentication provider."""
255
-
256
- def __init__(
257
- self,
258
- secret_key: str,
259
- algorithm: str = "HS256",
260
- issuer: Optional[str] = None,
261
- audience: Optional[str] = None,
262
- expiration_time: int = 3600
263
- ):
264
- """
265
- Initialize JWT provider.
266
-
267
- Args:
268
- secret_key: Secret key for signing tokens
269
- algorithm: JWT algorithm (HS256, RS256, etc.)
270
- issuer: Token issuer
271
- audience: Token audience
272
- expiration_time: Token expiration time in seconds
273
- """
274
- # PyJWT is now required
275
-
276
- self.secret_key = secret_key
277
- self.algorithm = algorithm
278
- self.issuer = issuer
279
- self.audience = audience
280
- self.expiration_time = expiration_time
281
-
282
- async def authenticate(self, credentials: dict[str, Any]) -> ATokenInfo:
283
- """Create JWT token from user credentials."""
284
- import asyncio
285
-
286
- def _authenticate():
287
- jwt = _get_jwt()
288
- # In a real implementation, you'd validate credentials against a database
289
- user_id = credentials.get('user_id')
290
- if not user_id:
291
- raise AuthenticationError("user_id required for JWT authentication")
292
-
293
- now = time.time()
294
- payload = {
295
- 'sub': user_id,
296
- 'iat': now,
297
- 'exp': now + self.expiration_time,
298
- **{k: v for k, v in credentials.items() if k not in ['user_id', 'password']}
299
- }
300
-
301
- if self.issuer:
302
- payload['iss'] = self.issuer
303
- if self.audience:
304
- payload['aud'] = self.audience
305
-
306
- token = jwt.encode(payload, self.secret_key, algorithm=self.algorithm)
307
-
308
- return ATokenInfo(
309
- access_token=token,
310
- token_type="Bearer",
311
- expires_in=self.expiration_time
312
- )
313
-
314
- return await asyncio.to_thread(_authenticate)
315
-
316
- async def validate_token(self, token: str) -> AUserInfo:
317
- """Validate JWT token."""
318
- import asyncio
319
-
320
- def _validate():
321
- jwt = _get_jwt()
322
- try:
323
- payload = jwt.decode(
324
- token,
325
- self.secret_key,
326
- algorithms=[self.algorithm],
327
- issuer=self.issuer,
328
- audience=self.audience
329
- )
330
-
331
- return AUserInfo(
332
- user_id=payload['sub'],
333
- username=payload.get('username'),
334
- email=payload.get('email'),
335
- roles=payload.get('roles', []),
336
- attributes=payload
337
- )
338
-
339
- except jwt.ExpiredSignatureError:
340
- raise TokenExpiredError("JWT token has expired")
341
- except jwt.InvalidTokenError as e:
342
- raise AuthenticationError(f"Invalid JWT token: {e}")
343
-
344
- return await asyncio.to_thread(_validate)
345
-
346
- async def refresh_token(self, refresh_token: str) -> ATokenInfo:
347
- """Refresh JWT token (create new token from existing)."""
348
- jwt = _get_jwt()
349
- try:
350
- # Validate existing token (ignore expiration for refresh)
351
- payload = jwt.decode(
352
- refresh_token,
353
- self.secret_key,
354
- algorithms=[self.algorithm],
355
- options={"verify_exp": False}
356
- )
357
-
358
- # Create new token with same payload but new timestamps
359
- now = time.time()
360
- payload.update({
361
- 'iat': now,
362
- 'exp': now + self.expiration_time
363
- })
364
-
365
- new_token = jwt.encode(payload, self.secret_key, algorithm=self.algorithm)
366
-
367
- return ATokenInfo(
368
- access_token=new_token,
369
- token_type="Bearer",
370
- expires_in=self.expiration_time
371
- )
372
-
373
- except Exception as e:
374
- jwt_module = _get_jwt()
375
- if isinstance(e, jwt_module.InvalidTokenError):
376
- raise AuthenticationError(f"Invalid refresh token: {e}")
377
- raise
378
-
379
-
380
- class SAMLProvider(AAuthProvider):
381
- """SAML 2.0 authentication provider (simplified implementation)."""
382
-
383
- def __init__(
384
- self,
385
- idp_url: str,
386
- sp_entity_id: str,
387
- certificate_path: Optional[str] = None
388
- ):
389
- """
390
- Initialize SAML provider.
391
-
392
- Args:
393
- idp_url: Identity Provider URL
394
- sp_entity_id: Service Provider entity ID
395
- certificate_path: Path to IdP certificate for validation
396
- """
397
- self.idp_url = idp_url
398
- self.sp_entity_id = sp_entity_id
399
- self.certificate_path = certificate_path
400
-
401
- logger.warning("SAML provider is a simplified implementation. Use a full SAML library for production.")
402
-
403
- async def authenticate(self, credentials: dict[str, Any]) -> ATokenInfo:
404
- """Authenticate using SAML (simplified)."""
405
- # This is a placeholder implementation
406
- # In practice, you'd use a library like python3-saml
407
- raise AuthenticationError("SAML authentication requires a full SAML library implementation")
408
-
409
- async def validate_token(self, token: str) -> AUserInfo:
410
- """Validate SAML token (simplified)."""
411
- # This is a placeholder implementation
412
- raise AuthenticationError("SAML token validation requires a full SAML library implementation")
413
-
414
- async def refresh_token(self, refresh_token: str) -> ATokenInfo:
415
- """SAML doesn't typically support token refresh."""
416
- raise AuthenticationError("SAML does not support token refresh")
417
-
418
- def get_login_url(self, return_url: str) -> str:
419
- """Get SAML login URL."""
420
- # This would generate a proper SAML AuthnRequest
421
- params = {
422
- 'SAMLRequest': base64.b64encode(f'<saml:AuthnRequest><saml:Issuer>{self.sp_entity_id}</saml:Issuer></saml:AuthnRequest>'.encode()).decode(),
423
- 'RelayState': return_url
424
- }
425
-
426
- return f"{self.idp_url}?{urlencode(params)}"
427
-
428
-
429
- class EnterpriseAuth:
430
- """Enterprise authentication manager."""
431
-
432
- def __init__(self):
433
- self._providers = {}
434
- self._active_provider = None
435
-
436
- def add_provider(self, name: str, provider: AAuthProvider):
437
- """Add authentication provider."""
438
- self._providers[name] = provider
439
-
440
- def set_active_provider(self, name: str):
441
- """Set active authentication provider."""
442
- if name not in self._providers:
443
- raise AuthenticationError(f"Provider '{name}' not found")
444
- self._active_provider = name
445
-
446
- def get_provider(self, name: Optional[str] = None) -> AAuthProvider:
447
- """Get authentication provider."""
448
- if name is None:
449
- name = self._active_provider
450
-
451
- if name is None:
452
- raise AuthenticationError("No active provider set")
453
-
454
- if name not in self._providers:
455
- raise AuthenticationError(f"Provider '{name}' not found")
456
-
457
- return self._providers[name]
458
-
459
- async def authenticate(self, credentials: dict[str, Any], provider: Optional[str] = None) -> ATokenInfo:
460
- """Authenticate using specified or active provider."""
461
- provider_instance = self.get_provider(provider)
462
- return await provider_instance.authenticate(credentials)
463
-
464
- async def validate_token(self, token: str, provider: Optional[str] = None) -> AUserInfo:
465
- """Validate token using specified or active provider."""
466
- provider_instance = self.get_provider(provider)
467
- return await provider_instance.validate_token(token)
468
-
469
- async def refresh_token(self, refresh_token: str, provider: Optional[str] = None) -> ATokenInfo:
470
- """Refresh token using specified or active provider."""
471
- provider_instance = self.get_provider(provider)
472
- return await provider_instance.refresh_token(refresh_token)
473
-
474
- def list_providers(self) -> list[str]:
475
- """List available providers."""
476
- return list(self._providers.keys())
477
-
478
- def remove_provider(self, name: str):
479
- """Remove authentication provider."""
480
- if name in self._providers:
481
- del self._providers[name]
482
- if self._active_provider == name:
483
- self._active_provider = None
484
-