osbot-utils 2.54.0__tar.gz → 2.56.0__tar.gz

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 (413) hide show
  1. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/PKG-INFO +2 -2
  2. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/README.md +1 -1
  3. osbot_utils-2.54.0/osbot_utils/helpers/html/Dict_To_Css.py → osbot_utils-2.56.0/osbot_utils/helpers/html/Dict__To__Css.py +1 -1
  4. osbot_utils-2.56.0/osbot_utils/helpers/html/Dict__To__Html.py +95 -0
  5. osbot_utils-2.56.0/osbot_utils/helpers/html/Dict__To__Tags.py +137 -0
  6. osbot_utils-2.56.0/osbot_utils/helpers/html/Html__To__Dict.py +102 -0
  7. osbot_utils-2.56.0/osbot_utils/helpers/html/Html__To__Tag.py +19 -0
  8. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Base.py +42 -12
  9. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Html.py +1 -1
  10. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Style.py +3 -3
  11. osbot_utils-2.56.0/osbot_utils/helpers/html/Tag__Text.py +7 -0
  12. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache.py +10 -10
  13. osbot_utils-2.56.0/osbot_utils/helpers/safe_str/Safe_Str__Html.py +17 -0
  14. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__Text__Dangerous.py +1 -4
  15. osbot_utils-2.56.0/osbot_utils/version +1 -0
  16. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/pyproject.toml +1 -1
  17. osbot_utils-2.54.0/osbot_utils/helpers/html/Dict_To_Html.py +0 -59
  18. osbot_utils-2.54.0/osbot_utils/helpers/html/Dict_To_Tags.py +0 -87
  19. osbot_utils-2.54.0/osbot_utils/helpers/html/Html_To_Dict.py +0 -85
  20. osbot_utils-2.54.0/osbot_utils/helpers/html/Html_To_Tag.py +0 -20
  21. osbot_utils-2.54.0/osbot_utils/version +0 -1
  22. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/LICENSE +0 -0
  23. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/__init__.py +0 -0
  24. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
  25. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
  26. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
  27. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/base_classes/__init__.py +0 -0
  28. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/context_managers/__init__.py +0 -0
  29. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/context_managers/async_invoke.py +0 -0
  30. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
  31. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/__init__.py +0 -0
  32. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/classes/__init__.py +0 -0
  33. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/classes/singleton.py +0 -0
  34. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/lists/__init__.py +0 -0
  35. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
  36. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/lists/group_by.py +0 -0
  37. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/lists/index_by.py +0 -0
  38. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/__init__.py +0 -0
  39. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/cache.py +0 -0
  40. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
  41. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
  42. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
  43. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
  44. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
  45. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/catch.py +0 -0
  46. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/context.py +0 -0
  47. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
  48. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
  49. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
  50. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
  51. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
  52. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
  53. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/fluent/Fluent_List.py +0 -0
  54. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/fluent/__init__.py +0 -0
  55. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/CFormat.py +0 -0
  56. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/CPrint.py +0 -0
  57. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
  58. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
  59. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Guid.py +0 -0
  60. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
  61. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Local_Cache.py +0 -0
  62. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Local_Caches.py +0 -0
  63. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Obj_Id.py +0 -0
  64. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Print_Table.py +0 -0
  65. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Python_Audit.py +0 -0
  66. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Random_Guid.py +0 -0
  67. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
  68. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Random_Seed.py +0 -0
  69. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Safe_Id.py +0 -0
  70. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
  71. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
  72. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Type_Registry.py +0 -0
  73. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/Zip_Bytes.py +0 -0
  74. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/__init__.py +0 -0
  75. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast.py +0 -0
  76. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
  77. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
  78. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
  79. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
  80. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
  81. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
  82. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
  83. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/__init__.py +0 -0
  84. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
  85. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
  86. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
  87. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
  88. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
  89. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
  90. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
  91. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
  92. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
  93. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
  94. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
  95. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
  96. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
  97. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
  98. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
  99. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
  100. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
  101. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
  102. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
  103. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
  104. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
  105. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
  106. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
  107. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
  108. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
  109. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
  110. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
  111. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
  112. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
  113. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
  114. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
  115. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
  116. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
  117. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
  118. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
  119. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
  120. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
  121. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
  122. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
  123. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
  124. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
  125. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
  126. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
  127. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
  128. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
  129. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
  130. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
  131. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
  132. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
  133. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
  134. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
  135. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
  136. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
  137. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
  138. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
  139. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
  140. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
  141. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
  142. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
  143. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
  144. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
  145. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
  146. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
  147. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
  148. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
  149. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
  150. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  151. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
  152. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
  153. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
  154. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
  155. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
  156. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
  157. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
  158. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/Duration.py +0 -0
  159. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/__init__.py +0 -0
  160. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/decorators/__init__.py +0 -0
  161. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/decorators/capture_duration.py +0 -0
  162. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/decorators/duration.py +0 -0
  163. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/decorators/print_duration.py +0 -0
  164. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/schemas/Schema__Duration.py +0 -0
  165. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/duration/schemas/__init__.py +0 -0
  166. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/Flow.py +0 -0
  167. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/Task.py +0 -0
  168. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/__init__.py +0 -0
  169. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/actions/Flow__Data.py +0 -0
  170. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/actions/Flow__Events.py +0 -0
  171. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/actions/Flow__Stats__Collector.py +0 -0
  172. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/actions/Task__Stats__Collector.py +0 -0
  173. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/actions/__init__.py +0 -0
  174. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
  175. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
  176. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
  177. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
  178. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
  179. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
  180. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
  181. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Schema__Flow__Artifact.py +0 -0
  182. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/Schema__Flow__Result.py +0 -0
  183. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
  184. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow.py +0 -0
  185. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Data.py +0 -0
  186. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event.py +0 -0
  187. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event__Data.py +0 -0
  188. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Log.py +0 -0
  189. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Stats.py +0 -0
  190. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Status.py +0 -0
  191. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Task__Data.py +0 -0
  192. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/Schema__Task__Stats.py +0 -0
  193. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/flows/schemas/__init__.py +0 -0
  194. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
  195. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
  196. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
  197. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
  198. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/generators/__init__.py +0 -0
  199. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
  200. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
  201. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
  202. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
  203. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
  204. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
  205. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/html/__init__.py +0 -0
  206. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/__init__.py +0 -0
  207. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/actions/LLM_Request__Execute.py +0 -0
  208. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/actions/Type_Safe__Schema_For__LLMs.py +0 -0
  209. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/actions/__init__.py +0 -0
  210. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder.py +0 -0
  211. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder__Open_AI.py +0 -0
  212. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/builders/LLM_Request__Factory.py +0 -0
  213. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/builders/__init__.py +0 -0
  214. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/LLM_Cache__Path_Generator.py +0 -0
  215. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__File_System.py +0 -0
  216. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__Storage.py +0 -0
  217. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Local__Folder.py +0 -0
  218. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Sqlite.py +0 -0
  219. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/cache/__init__.py +0 -0
  220. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/platforms/__init__.py +0 -0
  221. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/platforms/open_ai/API__LLM__Open_AI.py +0 -0
  222. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/platforms/open_ai/__init__.py +0 -0
  223. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Cache__Index.py +0 -0
  224. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request.py +0 -0
  225. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Data.py +0 -0
  226. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Function_Call.py +0 -0
  227. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Content.py +0 -0
  228. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Role.py +0 -0
  229. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response.py +0 -0
  230. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response__Cache.py +0 -0
  231. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/llms/schemas/__init__.py +0 -0
  232. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
  233. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
  234. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
  235. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
  236. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
  237. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
  238. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
  239. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
  240. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
  241. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
  242. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
  243. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
  244. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
  245. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
  246. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  247. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/python_compatibility/__init__.py +0 -0
  248. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/python_compatibility/python_3_8.py +0 -0
  249. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str.py +0 -0
  250. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Name.py +0 -0
  251. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Path.py +0 -0
  252. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__Hash.py +0 -0
  253. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__Text.py +0 -0
  254. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/Safe_Str__Url.py +0 -0
  255. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/safe_str/__init__.py +0 -0
  256. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
  257. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
  258. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
  259. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
  260. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
  261. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
  262. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
  263. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
  264. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
  265. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
  266. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
  267. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
  268. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
  269. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
  270. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
  271. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
  272. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
  273. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
  274. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
  275. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
  276. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
  277. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
  278. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
  279. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
  280. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
  281. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
  282. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
  283. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
  284. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
  285. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
  286. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
  287. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
  288. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
  289. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
  290. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
  291. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
  292. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
  293. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
  294. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
  295. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
  296. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
  297. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
  298. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
  299. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
  300. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
  301. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
  302. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
  303. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
  304. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
  305. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +0 -0
  306. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
  307. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
  308. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
  309. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
  310. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
  311. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
  312. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
  313. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/trace/__init__.py +0 -0
  314. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
  315. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
  316. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__File.py +0 -0
  317. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
  318. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +0 -0
  319. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +0 -0
  320. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/__init__.py +0 -0
  321. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
  322. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
  323. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
  324. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +0 -0
  325. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
  326. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
  327. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Catch.py +0 -0
  328. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
  329. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Hook_Method.py +0 -0
  330. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
  331. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Log_To_String.py +0 -0
  332. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Logging.py +0 -0
  333. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Patch_Print.py +0 -0
  334. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Profiler.py +0 -0
  335. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Pytest.py +0 -0
  336. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Stderr.py +0 -0
  337. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Stdout.py +0 -0
  338. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
  339. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_File.py +0 -0
  340. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Folder.py +0 -0
  341. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
  342. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
  343. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Zip.py +0 -0
  344. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
  345. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Unit_Test.py +0 -0
  346. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/Unzip_File.py +0 -0
  347. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/__init__.py +0 -0
  348. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/performance/Performance_Measure__Session.py +0 -0
  349. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/performance/__init__.py +0 -0
  350. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py +0 -0
  351. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py +0 -0
  352. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/testing/performance/models/__init__.py +0 -0
  353. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe.py +0 -0
  354. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__Base.py +0 -0
  355. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__Dict.py +0 -0
  356. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__List.py +0 -0
  357. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__Method.py +0 -0
  358. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__Set.py +0 -0
  359. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/Type_Safe__Tuple.py +0 -0
  360. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/__init__.py +0 -0
  361. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/decorators/__init__.py +0 -0
  362. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/decorators/type_safe.py +0 -0
  363. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/methods/__init__.py +0 -0
  364. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/methods/type_safe_property.py +0 -0
  365. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Annotations.py +0 -0
  366. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Cache.py +0 -0
  367. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Convert.py +0 -0
  368. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor.py +0 -0
  369. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor__Type_Registry.py +0 -0
  370. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py +0 -0
  371. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py +0 -0
  372. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py +0 -0
  373. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/Type_Safe__Validation.py +0 -0
  374. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/shared/__init__.py +0 -0
  375. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py +0 -0
  376. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py +0 -0
  377. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py +0 -0
  378. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py +0 -0
  379. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py +0 -0
  380. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py +0 -0
  381. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/steps/__init__.py +0 -0
  382. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/Type_Safe__Validator.py +0 -0
  383. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/Validator__Max.py +0 -0
  384. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/Validator__Min.py +0 -0
  385. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/Validator__One_Of.py +0 -0
  386. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/Validator__Regex.py +0 -0
  387. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/type_safe/validators/__init__.py +0 -0
  388. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Assert.py +0 -0
  389. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Call_Stack.py +0 -0
  390. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Csv.py +0 -0
  391. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Dev.py +0 -0
  392. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Env.py +0 -0
  393. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Exceptions.py +0 -0
  394. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Files.py +0 -0
  395. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Functions.py +0 -0
  396. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Http.py +0 -0
  397. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Int.py +0 -0
  398. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Json.py +0 -0
  399. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Json_Cache.py +0 -0
  400. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Lists.py +0 -0
  401. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Misc.py +0 -0
  402. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Objects.py +0 -0
  403. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Png.py +0 -0
  404. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Process.py +0 -0
  405. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Python_Logger.py +0 -0
  406. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Regex.py +0 -0
  407. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Status.py +0 -0
  408. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Str.py +0 -0
  409. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Threads.py +0 -0
  410. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Toml.py +0 -0
  411. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Version.py +0 -0
  412. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/Zip.py +0 -0
  413. {osbot_utils-2.54.0 → osbot_utils-2.56.0}/osbot_utils/utils/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.54.0
3
+ Version: 2.56.0
4
4
  Summary: OWASP Security Bot - Utils
5
5
  License: MIT
6
6
  Author: Dinis Cruz
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  Powerful Python util methods and classes that simplify common apis and tasks.
25
25
 
26
- ![Current Release](https://img.shields.io/badge/release-v2.54.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v2.56.0-blue)
27
27
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
28
28
 
29
29
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Powerful Python util methods and classes that simplify common apis and tasks.
4
4
 
5
- ![Current Release](https://img.shields.io/badge/release-v2.54.0-blue)
5
+ ![Current Release](https://img.shields.io/badge/release-v2.56.0-blue)
6
6
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
7
7
 
8
8
 
@@ -1,7 +1,7 @@
1
1
  from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
2
2
 
3
3
 
4
- class Dict_To_Css(Kwargs_To_Self):
4
+ class Dict__To__Css(Kwargs_To_Self):
5
5
  css: dict
6
6
 
7
7
 
@@ -0,0 +1,95 @@
1
+ HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
2
+ HTML_DEFAULT_DOCTYPE_VALUE = "<!DOCTYPE html>\n"
3
+
4
+ class Dict__To__Html:
5
+ def __init__(self, root, include_doctype=True, doctype=HTML_DEFAULT_DOCTYPE_VALUE):
6
+ self.self_closing_tags = HTML_SELF_CLOSING_TAGS # Define a list of self-closing tags
7
+ self.root = root
8
+ self.include_doctype = include_doctype
9
+ self.doctype = doctype
10
+
11
+ def convert(self):
12
+ html = self.convert_element(self.root, 0)
13
+ if self.include_doctype:
14
+ return self.doctype + html
15
+ return html
16
+
17
+ def convert_attrs(self, attrs):
18
+ attrs_str_parts = [] # List to hold each attribute's string representation
19
+ for key, value in attrs.items():
20
+ if value is None: # Handle None values
21
+ attr_str = f'{key}'
22
+ elif '"' in str(value): # Check if the attribute value contains double quotes
23
+ escaped_value = "&quot;".join(str(value).split("\"")) # If so, escape double quotes and format the attribute string
24
+ attr_str = f'{key}="{escaped_value}"'
25
+ else:
26
+ attr_str = f'{key}="{value}"' # If not, simply format the attribute string
27
+ attrs_str_parts.append(attr_str)
28
+
29
+ attrs_str = ' '.join(attrs_str_parts) # Join the parts into the final attributes string
30
+
31
+ if attrs_str:
32
+ attrs_str = " " + attrs_str # Prepend a space if there are attributes
33
+ return attrs_str
34
+
35
+ def convert_element(self, element, indent_level):
36
+ """Recursively converts a dictionary to an HTML string with indentation."""
37
+ # Check if this is a text node
38
+ if element.get("type") == "text":
39
+ return element.get("data", "") # Return text content directly for text nodes
40
+
41
+ tag = element.get("tag")
42
+ attrs = element.get("attrs", {})
43
+ children = element.get("children", [])
44
+
45
+ attrs_str = self.convert_attrs(attrs) # Convert attributes dictionary to a string
46
+ indent = " " * indent_level # Indentation for the current level, assuming 4 spaces per indent level
47
+
48
+ # Handle self-closing tags
49
+ if tag in self.self_closing_tags and not children: # Check if the tag is self-closing and has no children
50
+ return f"{indent}<{tag}{attrs_str} />\n"
51
+
52
+ # Start building the HTML
53
+ html = f"{indent}<{tag}{attrs_str}>" # Opening tag with indentation
54
+
55
+ # Separate children into text nodes and element nodes
56
+ text_nodes = [child for child in children if child.get("type") == "text"]
57
+ element_nodes = [child for child in children if child.get("type") != "text"]
58
+
59
+ # If there are only element nodes, add a newline after the opening tag
60
+ if element_nodes and not text_nodes:
61
+ html += "\n"
62
+
63
+ # Process children, maintaining the original order but with proper formatting
64
+ if children:
65
+ # Track if we're currently in a text section or element section
66
+ # This helps us add newlines only between elements, not text
67
+ previous_was_element = False
68
+
69
+ for child in children:
70
+ if child.get("type") == "text":
71
+ # Text node - directly append content
72
+ html += child.get("data", "")
73
+ previous_was_element = False
74
+ else:
75
+ # Element node - format with proper indentation
76
+ if previous_was_element:
77
+ # If previous child was also an element, we may already have a newline
78
+ if not html.endswith("\n"):
79
+ html += "\n"
80
+
81
+ html += self.convert_element(child, indent_level + 1)
82
+ previous_was_element = True
83
+
84
+ # Handle closing tag based on content
85
+ if element_nodes and not text_nodes:
86
+ # If only element children, add indented closing tag
87
+ html += f"{indent}</{tag}>\n"
88
+ elif children: # Any type of children
89
+ # If mixed content or only text, add closing tag without indentation
90
+ html += f"</{tag}>\n"
91
+ else:
92
+ # Empty tag, replace with self-contained format
93
+ html = f"{indent}<{tag}{attrs_str}></{tag}>\n"
94
+
95
+ return html
@@ -0,0 +1,137 @@
1
+ from osbot_utils.helpers.html.Dict__To__Html import HTML_SELF_CLOSING_TAGS
2
+ from osbot_utils.helpers.html.Tag__Base import Tag__Base
3
+ from osbot_utils.helpers.html.Tag__Body import Tag__Body
4
+ from osbot_utils.helpers.html.Tag__Head import Tag__Head
5
+ from osbot_utils.helpers.html.Tag__Html import Tag__Html
6
+ from osbot_utils.helpers.html.Tag__Link import Tag__Link
7
+ from osbot_utils.helpers.html.Tag__Text import Tag__Text
8
+
9
+
10
+ class Dict__To__Tags:
11
+
12
+ def __init__(self, root):
13
+ self.root = root
14
+
15
+ def convert(self):
16
+ return self.convert_element(self.root)
17
+
18
+ def convert_element(self, element):
19
+ tag_name = element.get("tag")
20
+
21
+ # Handle special tag types with dedicated conversion methods
22
+ if tag_name == 'html':
23
+ return self.convert_to__tag__html(element)
24
+ elif tag_name == 'head':
25
+ return self.convert_to__tag__head(element, 0) # Default indent 0
26
+ elif tag_name == 'link':
27
+ return self.convert_to__tag__link(element)
28
+ else:
29
+ # Default case: convert to a generic Tag__Base
30
+ return self.convert_to__tag(Tag__Base, element, 0) # Default indent 0
31
+
32
+ def collect_inner_text(self, element):
33
+ """Extract all text from an element's text node children."""
34
+ inner_text = ""
35
+ for child in element.get("children", []):
36
+ if child.get("type") == "text":
37
+ inner_text += child.get("data", "")
38
+ return inner_text
39
+
40
+ def convert_to__tag(self, target_tag, element, indent):
41
+ if element.get("type") == "text":
42
+ # Handle text nodes directly
43
+ return Tag__Text(element.get("data", ""))
44
+
45
+ tag_name = element.get("tag")
46
+ attrs = element.get("attrs", {})
47
+ children = element.get("children", [])
48
+ end_tag = tag_name not in HTML_SELF_CLOSING_TAGS
49
+ tag_indent = indent + 1
50
+
51
+ # Collect inner text from all text node children
52
+ inner_html = self.collect_inner_text(element)
53
+
54
+ tag_kwargs = dict(
55
+ tag_name = tag_name,
56
+ attributes = attrs,
57
+ end_tag = end_tag,
58
+ indent = tag_indent,
59
+ inner_html = inner_html
60
+ )
61
+
62
+ tag = target_tag(**tag_kwargs)
63
+
64
+ # Process only element nodes as children (text is already handled via inner_html)
65
+ for child in children:
66
+ if child.get("type") != "text": # Skip text nodes, they're in inner_html
67
+ child_tag = self.convert_to__tag(Tag__Base, child, tag_indent)
68
+ tag.elements.append(child_tag)
69
+
70
+ return tag
71
+
72
+ def convert_to__tag__head(self, element, indent):
73
+ attrs = element.get("attrs", {})
74
+ children = element.get("children", [])
75
+
76
+ head_indent = indent + 1
77
+ tag_head = Tag__Head(indent=head_indent, **attrs)
78
+
79
+ for child in children:
80
+ tag_name = child.get("tag")
81
+
82
+ if tag_name == 'title':
83
+ # Extract title text from text node children
84
+ tag_head.title = self.collect_inner_text(child)
85
+ elif tag_name == 'link':
86
+ tag_head.links.append(self.convert_to__tag__link(child))
87
+ elif tag_name == 'meta':
88
+ tag_head.elements.append(self.convert_to__tag(Tag__Base, child, head_indent))
89
+ elif tag_name == 'style':
90
+ # For style tags, collect the CSS content from text nodes
91
+ style_element = self.convert_to__tag(Tag__Base, child, head_indent)
92
+ tag_head.elements.append(style_element)
93
+ else:
94
+ # Handle any other head elements
95
+ tag_head.elements.append(self.convert_to__tag(Tag__Base, child, head_indent))
96
+
97
+ return tag_head
98
+
99
+ def convert_to__tag__html(self, element):
100
+ attrs = element.get("attrs", {})
101
+ children = element.get("children", [])
102
+ lang = attrs.get("lang")
103
+
104
+ tag_html = Tag__Html(attributes=attrs, lang=lang, doc_type=False)
105
+
106
+ # Initialize head and body if not found
107
+ head_found = False
108
+ body_found = False
109
+
110
+ for child in children:
111
+ tag_name = child.get("tag")
112
+
113
+ if tag_name == 'head':
114
+ tag_html.head = self.convert_to__tag__head(child, tag_html.indent)
115
+ head_found = True
116
+ elif tag_name == 'body':
117
+ tag_html.body = self.convert_to__tag(Tag__Body, child, tag_html.indent)
118
+ body_found = True
119
+ else:
120
+ # Log unexpected child elements of html
121
+ print(f'Unexpected child of html tag: {tag_name}')
122
+
123
+ # Handle missing head or body (required for valid HTML structure)
124
+ if not head_found:
125
+ #print("Warning: No head element found, creating empty one")
126
+ tag_html.head = Tag__Head(indent=tag_html.indent + 1)
127
+
128
+ if not body_found:
129
+ #print("Warning: No body element found, creating empty one")
130
+ tag_html.body = Tag__Body(indent=tag_html.indent + 1)
131
+
132
+ return tag_html
133
+
134
+ def convert_to__tag__link(self, element):
135
+ attrs = element.get("attrs", {})
136
+ tag_link = Tag__Link(**attrs)
137
+ return tag_link
@@ -0,0 +1,102 @@
1
+ from html.parser import HTMLParser
2
+
3
+ HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
4
+ STRING__DATA_TEXT = 'TEXT:'
5
+
6
+ class Html__To__Dict(HTMLParser):
7
+ def __init__(self, html):
8
+ super().__init__()
9
+ self.root = None # No root initially
10
+ self.current = None # No current node at the start
11
+ self.stack = [] # Empty stack for hierarchy management
12
+ self.html = html or ''
13
+ self.void_elements = HTML_SELF_CLOSING_TAGS # List of void elements that are self-closing by nature
14
+ self.strip_text_data = True
15
+
16
+ def convert(self):
17
+ self.feed(self.html)
18
+ return self.root
19
+
20
+ def handle_starttag(self, tag, attrs):
21
+ new_tag = {"tag": tag, "attrs": dict(attrs), "children": []}
22
+
23
+ if self.current is None:
24
+ # When the first tag is encountered, it becomes the root
25
+ self.root = new_tag
26
+ self.current = new_tag
27
+ else:
28
+ # Otherwise, append the new tag as a child of the current tag
29
+ self.current["children"].append(new_tag)
30
+
31
+ # If this tag is not a void element, push it onto the stack
32
+ if tag.lower() not in self.void_elements:
33
+ self.stack.append(new_tag)
34
+ self.current = new_tag
35
+
36
+ def handle_endtag(self, tag):
37
+ # Find and pop the matching start tag
38
+ if tag.lower() not in self.void_elements and len(self.stack) > 1:
39
+ # Look for the matching start tag in the stack
40
+ for i in range(len(self.stack) - 1, 0, -1):
41
+ if self.stack[i]["tag"].lower() == tag.lower():
42
+ # Pop all tags up to and including the matching start tag
43
+ self.stack = self.stack[:i]
44
+ break
45
+ # Update current to the top of stack
46
+ self.current = self.stack[-1]
47
+
48
+ def handle_data(self, data):
49
+ if data.strip(): # Ignore whitespace
50
+ # Create a text node as a child
51
+ text_node = {"type": "text", "data": data}
52
+ self.current["children"].append(text_node)
53
+
54
+ def print__generate_lines(self, node, indent="", last=True, is_root=True):
55
+ lines = []
56
+
57
+ prefix = "" if is_root else ("└── " if last else "├── ")
58
+
59
+ if node.get("type") == "text":
60
+ text_data = node.get('data')
61
+ if self.strip_text_data:
62
+ text_data = text_data.strip()
63
+ lines.append(f"{indent}{prefix}{STRING__DATA_TEXT} {text_data}")
64
+ else:
65
+ tag = node.get("tag")
66
+ attrs = node.get("attrs", {})
67
+ children = node.get("children", [])
68
+ attrs_str = ' '.join(f'{key}="{value}"' for key, value in attrs.items())
69
+ attrs_str = f' ({attrs_str})' if attrs_str else ''
70
+
71
+ lines.append(f"{indent}{prefix}{tag}{attrs_str}")
72
+
73
+ child_indent = indent + (" " if last else "│ ")
74
+
75
+ for i, child in enumerate(children):
76
+ is_last = i == len(children) - 1
77
+ child_lines = self.print__generate_lines(child, indent=child_indent, last=is_last, is_root=False)
78
+ lines.extend(child_lines if isinstance(child_lines, list) else [child_lines])
79
+
80
+ return lines if is_root else "\n".join(lines)
81
+
82
+ def print(self, just_return_lines=False):
83
+ if self.root:
84
+ lines = self.print__generate_lines(self.root, is_root=True)
85
+ if just_return_lines:
86
+ return lines
87
+ else:
88
+ self.print__lines(lines)
89
+ return self
90
+
91
+ def print__lines(self, lines):
92
+ for line in lines:
93
+ print(line)
94
+
95
+
96
+ def html_to_dict(html_code: str) -> dict:
97
+ try:
98
+ html_to_dict = Html__To__Dict(html_code)
99
+ html_dict = html_to_dict.convert()
100
+ return html_dict
101
+ except: # todo: see if there is a better Exception to capture
102
+ return None # if we couldn't parse the html, just return None
@@ -0,0 +1,19 @@
1
+ from osbot_utils.helpers.html.Dict__To__Tags import Dict__To__Tags
2
+ from osbot_utils.helpers.html.Html__To__Dict import Html__To__Dict
3
+
4
+
5
+ class Html__To__Tag:
6
+
7
+ def __init__(self,html):
8
+ self.html_to_dict = Html__To__Dict(html)
9
+
10
+ def __enter__(self):
11
+ return self.convert()
12
+
13
+ def __exit__(self, exc_type, exc_val, exc_tb):
14
+ return
15
+
16
+ def convert(self):
17
+ html_dict = self.html_to_dict.convert()
18
+ html_tag = Dict__To__Tags(html_dict).convert()
19
+ return html_tag
@@ -1,11 +1,10 @@
1
- from collections import defaultdict
2
-
3
- from osbot_utils.base_classes.Kwargs_To_Self import Kwargs_To_Self
4
- from osbot_utils.utils.Files import file_create
1
+ from collections import defaultdict
2
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
3
+ from osbot_utils.utils.Files import file_create
5
4
 
6
5
  INDENT_SIZE = 4
7
6
 
8
- class Tag__Base(Kwargs_To_Self):
7
+ class Tag__Base(Type_Safe):
9
8
  attributes : dict
10
9
  elements : list
11
10
  end_tag : bool = True
@@ -54,23 +53,43 @@ class Tag__Base(Kwargs_To_Self):
54
53
 
55
54
  def render_element(self):
56
55
  html_attributes = self.render_attributes()
57
- html_elements = self.render_elements()
58
- element_indent = " " * self.indent * INDENT_SIZE
56
+ element_indent = " " * self.indent * INDENT_SIZE
59
57
 
60
58
  html = f"{element_indent}<{self.tag_name}"
61
59
  if html_attributes:
62
60
  html += f" {html_attributes}"
61
+
63
62
  if self.end_tag:
64
63
  html += ">"
64
+
65
+ # Check for text nodes and regular element nodes
66
+ text_nodes = [e for e in self.elements if hasattr(e, 'type') and e.type == 'text']
67
+ element_nodes = [e for e in self.elements if not hasattr(e, 'type') or e.type != 'text']
68
+
69
+ has_text = bool(text_nodes) or bool(self.inner_html)
70
+ has_elements = bool(element_nodes)
71
+
72
+ # Add inner_html if it exists
65
73
  if self.inner_html:
66
74
  html += self.inner_html
75
+
76
+ # Get the rendered element HTML
77
+ html_elements = self.render_elements()
78
+
79
+ # Add element children with proper formatting
67
80
  if html_elements:
68
- if self.new_line_before_elements:
81
+ # Only add newlines if we have element nodes and no text nodes,
82
+ # or if we explicitly want newlines before elements
83
+ if (has_elements and not has_text) or (self.new_line_before_elements and not has_text):
69
84
  html += "\n"
70
- html += f"{html_elements}"
71
- if self.new_line_before_elements:
85
+
86
+ html += html_elements
87
+
88
+ # Add closing newline and indent only for pure element content
89
+ if (has_elements and not has_text) or (self.new_line_before_elements and not has_text):
72
90
  html += "\n"
73
- html += element_indent
91
+ html += element_indent
92
+
74
93
  html += f"</{self.tag_name}>"
75
94
  else:
76
95
  html += "/>"
@@ -79,12 +98,23 @@ class Tag__Base(Kwargs_To_Self):
79
98
 
80
99
  def render_elements(self):
81
100
  html_elements = ""
101
+ has_element_nodes = False
102
+
82
103
  for index, element in enumerate(self.elements):
83
- if index:
104
+ # Handle text nodes
105
+ if hasattr(element, 'type') and element.type == 'text':
106
+ html_elements += element.data
107
+ continue
108
+
109
+ # Only add newlines between element nodes (not text nodes)
110
+ if has_element_nodes:
84
111
  html_elements += '\n'
112
+
113
+ has_element_nodes = True
85
114
  element.indent = self.indent + 1 # set the indent of the child element based on the current one
86
115
  html_element = element.render()
87
116
  html_elements += html_element
117
+
88
118
  return html_elements
89
119
 
90
120
  def render(self):
@@ -1,7 +1,7 @@
1
1
  from osbot_utils.helpers.html.Tag__Base import Tag__Base
2
2
  from osbot_utils.helpers.html.Tag__Body import Tag__Body
3
3
  from osbot_utils.helpers.html.Tag__Head import Tag__Head
4
- from osbot_utils.utils.Misc import str_to_bytes
4
+ from osbot_utils.utils.Misc import str_to_bytes
5
5
 
6
6
  ATTRIBUTES_NAMES__LINK = ['lang']
7
7
 
@@ -1,10 +1,10 @@
1
- from osbot_utils.helpers.html.Dict_To_Css import Dict_To_Css
2
- from osbot_utils.helpers.html.Tag__Base import Tag__Base, INDENT_SIZE
1
+ from osbot_utils.helpers.html.Dict__To__Css import Dict__To__Css
2
+ from osbot_utils.helpers.html.Tag__Base import Tag__Base, INDENT_SIZE
3
3
 
4
4
 
5
5
  class Tag__Style(Tag__Base):
6
6
  tag_name : str = 'style'
7
- dict_to_css : Dict_To_Css
7
+ dict_to_css : Dict__To__Css
8
8
 
9
9
  def add_css_entry(self, selector, data):
10
10
  self.dict_to_css.add_css_entry(selector,data)
@@ -0,0 +1,7 @@
1
+ class Tag__Text:
2
+ def __init__(self, data=""):
3
+ self.type = "text"
4
+ self.data = data
5
+
6
+ def render(self):
7
+ return self.data
@@ -1,13 +1,13 @@
1
- from typing import Dict, Optional, List
2
- from osbot_utils.helpers.Obj_Id import Obj_Id
3
- from osbot_utils.helpers.llms.schemas.Schema__LLM_Cache__Index import Schema__LLM_Cache__Index
4
- from osbot_utils.helpers.llms.schemas.Schema__LLM_Request import Schema__LLM_Request
5
- from osbot_utils.helpers.llms.schemas.Schema__LLM_Response import Schema__LLM_Response
6
- from osbot_utils.helpers.llms.schemas.Schema__LLM_Response__Cache import Schema__LLM_Response__Cache
7
- from osbot_utils.helpers.safe_str.Safe_Str__Hash import Safe_Str__Hash
8
- from osbot_utils.type_safe.Type_Safe import Type_Safe
9
- from osbot_utils.type_safe.decorators.type_safe import type_safe
10
- from osbot_utils.utils.Json import json_md5
1
+ from typing import Dict, Optional, List
2
+ from osbot_utils.helpers.Obj_Id import Obj_Id
3
+ from osbot_utils.helpers.llms.schemas.Schema__LLM_Cache__Index import Schema__LLM_Cache__Index
4
+ from osbot_utils.helpers.llms.schemas.Schema__LLM_Request import Schema__LLM_Request
5
+ from osbot_utils.helpers.llms.schemas.Schema__LLM_Response import Schema__LLM_Response
6
+ from osbot_utils.helpers.llms.schemas.Schema__LLM_Response__Cache import Schema__LLM_Response__Cache
7
+ from osbot_utils.helpers.safe_str.Safe_Str__Hash import Safe_Str__Hash
8
+ from osbot_utils.type_safe.Type_Safe import Type_Safe
9
+ from osbot_utils.type_safe.decorators.type_safe import type_safe
10
+ from osbot_utils.utils.Json import json_md5
11
11
 
12
12
  SIZE__VALUE_HASH = 10
13
13
 
@@ -0,0 +1,17 @@
1
+ import re
2
+ from osbot_utils.helpers.safe_str.Safe_Str import Safe_Str
3
+
4
+ # Define the size constant
5
+ TYPE_SAFE_STR__HTML__MAX_LENGTH = 1048576 # 1 megabyte in bytes
6
+
7
+ # A minimal regex that only filters out:
8
+ # - NULL byte (U+0000)
9
+ # - Control characters (U+0001 to U+0008, U+000B to U+000C, U+000E to U+001F)
10
+ # We explicitly allow:
11
+ # - Tab (U+0009), Line Feed (U+000A), and Carriage Return (U+000D)
12
+ # - All other Unicode characters
13
+ TYPE_SAFE_STR__HTML__REGEX = re.compile(r'[\x00\x01-\x08\x0B\x0C\x0E-\x1F]')
14
+
15
+ class Safe_Str__Html(Safe_Str):
16
+ max_length = TYPE_SAFE_STR__HTML__MAX_LENGTH
17
+ regex = TYPE_SAFE_STR__HTML__REGEX
@@ -6,7 +6,4 @@ TYPE_SAFE_STR__TEXT__DANGEROUS__REGEX = r'[^a-zA-Z0-9_\s!@#$%^&*()\[\]{}\-+
6
6
 
7
7
  class Safe_Str__Text__Dangerous(Safe_Str):
8
8
  regex = re.compile(TYPE_SAFE_STR__TEXT__DANGEROUS__REGEX)
9
- max_length = TYPE_SAFE_STR__TEXT__DANGEROUS__MAX_LENGTH
10
-
11
-
12
- Safe_Str__HTML = Safe_Str__Text__Dangerous # we can reuse this class for Safe_Str__HTML since the regex and size are the same
9
+ max_length = TYPE_SAFE_STR__TEXT__DANGEROUS__MAX_LENGTH
@@ -0,0 +1 @@
1
+ v2.56.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "osbot_utils"
3
- version = "v2.54.0"
3
+ version = "v2.56.0"
4
4
  description = "OWASP Security Bot - Utils"
5
5
  authors = ["Dinis Cruz <dinis.cruz@owasp.org>"]
6
6
  license = "MIT"
@@ -1,59 +0,0 @@
1
-
2
- HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
3
-
4
- class Dict_To_Html:
5
- def __init__(self, root):
6
- # Define a list of self-closing tags
7
- self.self_closing_tags =HTML_SELF_CLOSING_TAGS # {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
8
- self.root = root
9
-
10
- def convert(self):
11
- return self.convert_element(self.root, 0) # Start conversion with the root element and initial indentation level 0
12
-
13
- def convert_attrs(self, attrs):
14
- attrs_str_parts = [] # List to hold each attribute's string representation
15
- for key, value in attrs.items():
16
- if '"' in value: # Check if the attribute value contains double quotes
17
- escaped_value = "&quot;".join(value.split("\"")) # If so, escape double quotes and format the attribute string
18
- attr_str = f'{key}="{escaped_value}"'
19
- else:
20
- attr_str = f'{key}="{value}"' # If not, simply format the attribute string
21
- attrs_str_parts.append(attr_str)
22
-
23
- attrs_str = ' '.join(attrs_str_parts) # Join the parts into the final attributes string
24
-
25
- if attrs_str:
26
- attrs_str = " " + attrs_str # Prepend a space if there are attributes
27
- return attrs_str
28
-
29
- def convert_element(self, element, indent_level):
30
- """Recursively converts a dictionary to an HTML string with indentation."""
31
- tag = element.get("tag")
32
- attrs = element.get("attrs", {})
33
- children = element.get("children", [])
34
- data = element.get("data", "")
35
-
36
- attrs_str = self.convert_attrs(attrs) # Convert attributes dictionary to a string
37
- indent = " " * indent_level # Indentation for the current level, assuming 4 spaces per indent level
38
-
39
- if tag in self.self_closing_tags: # Check if the tag is self-closing
40
- return f"{indent}<{tag}{attrs_str} />\n"
41
-
42
- html = f"{indent}<{tag}{attrs_str}>" # Opening tag with indentation
43
- if not data:
44
- html += '\n'
45
-
46
- for child in children: # Process children with incremented indent level
47
- html += self.convert_element(child, indent_level + 1)
48
-
49
- if data: # Add data if present
50
- html += data
51
-
52
- if children: # Closing tag for non-self-closing tags, with indentation
53
- html += f"{indent}</{tag}>\n" # Add closing tag on a new line if there are children
54
- elif data:
55
- html += f"</{tag}>\n"
56
- else: # Place closing tag directly after opening tag if there are no children or data
57
- html = f"{indent}<{tag}{attrs_str}></{tag}>\n"
58
-
59
- return html