osbot-utils 2.67.0__tar.gz → 2.69.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.
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/PKG-INFO +2 -2
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/README.md +1 -1
- osbot_utils-2.69.0/osbot_utils/helpers/html/Html_Dict__To__Html.py +112 -0
- osbot_utils-2.69.0/osbot_utils/helpers/html/Html_Dict__To__Html_Document.py +49 -0
- osbot_utils-2.69.0/osbot_utils/helpers/html/Html_Dict__To__Html_Tags.py +147 -0
- osbot_utils-2.69.0/osbot_utils/helpers/html/Html_Document__To__Html_Dict.py +44 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Html__To__Html_Dict.py +4 -1
- osbot_utils-2.69.0/osbot_utils/helpers/html/schemas/Schema__Html_Node.py +12 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/schemas/Schema__Html_Node__Data.py +1 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder.py +9 -8
- osbot_utils-2.69.0/osbot_utils/helpers/llms/schemas/Safe_Str__LLM__Model_Name.py +10 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Data.py +2 -1
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py +0 -2
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py +5 -1
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py +6 -1
- osbot_utils-2.69.0/osbot_utils/version +1 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/pyproject.toml +1 -1
- osbot_utils-2.67.0/osbot_utils/helpers/html/Html_Dict__To__Html.py +0 -97
- osbot_utils-2.67.0/osbot_utils/helpers/html/Html_Dict__To__Html_Document.py +0 -37
- osbot_utils-2.67.0/osbot_utils/helpers/html/Html_Dict__To__Html_Tags.py +0 -138
- osbot_utils-2.67.0/osbot_utils/helpers/html/schemas/Schema__Html_Node.py +0 -10
- osbot_utils-2.67.0/osbot_utils/version +0 -1
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/LICENSE +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/base_classes/Cache_Pickle.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/base_classes/Kwargs_To_Disk.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/base_classes/Kwargs_To_Self.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/base_classes/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/context_managers/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/context_managers/async_invoke.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/context_managers/disable_root_loggers.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/classes/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/classes/singleton.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/lists/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/lists/filter_list.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/lists/group_by.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/lists/index_by.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/cache_on_function.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/cache_on_self.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/cache_on_tmp.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/capture_exception.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/capture_status.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/catch.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/context.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/depreciated.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/function_type_check.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/obj_as_context.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/remove_return_value.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/decorators/methods/required_fields.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/fluent/Fluent_Dict.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/fluent/Fluent_List.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/fluent/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/CFormat.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/CPrint.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Dependency_Manager.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Dict_To_Attr.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Guid.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Hashicorp_Secrets.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Local_Cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Local_Caches.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Obj_Id.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Print_Table.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Python_Audit.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Random_Guid.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Random_Guid_Short.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Random_Seed.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Safe_Id.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Str_ASCII.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Timestamp_Now.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Type_Registry.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/Zip_Bytes.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Base.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Load.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Merge.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Node.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Ast_Visit.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/Call_Tree.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Add.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Alias.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_And.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Argument.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Arguments.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Assert.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Assign.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Attribute.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Break.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Call.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Compare.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Constant.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Continue.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Dict.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Eq.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Expr.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_For.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Gt.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_GtE.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_If.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Import.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Import_From.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_In.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Is.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Keyword.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Lambda.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_List.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Load.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Lt.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_LtE.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Mod.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Module.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Mult.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Name.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Not.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Not_In.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Or.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Pass.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Pow.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Raise.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Return.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Set.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Slice.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Starred.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Store.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Sub.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Subscript.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Try.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Tuple.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_While.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_With.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_With_Item.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/Ast_Yield.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ast/nodes/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/Cache_Controller.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/Cache_Key_Generator.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/Cache_Metrics.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/Cache_On_Self.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/Cache_Storage.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_on_self/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Actions.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Config.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Invoke.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Row.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/Cache__Requests__Table.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/cache_requests/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/Duration.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/decorators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/decorators/capture_duration.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/decorators/duration.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/decorators/print_duration.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/schemas/Schema__Duration.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/duration/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/Flow.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/Task.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/actions/Flow__Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/actions/Flow__Events.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/actions/Flow__Stats__Collector.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/actions/Task__Stats__Collector.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/actions/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/decorators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/decorators/flow.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/decorators/task.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Flow_Run__Config.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Flow_Run__Event.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Flow_Run__Event_Type.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Schema__Flow__Artifact.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/Schema__Flow__Result.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/models/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Event__Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Log.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Stats.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Status.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Flow__Task__Data.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/Schema__Task__Stats.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/flows/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/generators/Generator_Context_Manager.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/generators/Generator_Manager.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/generators/Model__Generator_State.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/generators/Model__Generator_Target.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/generators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/CSS_Dict__To__Css.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Html__To__Html_Document.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Html__To__Html_Tag.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Base.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Body.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Div.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__H.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__HR.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Head.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Html.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Link.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Style.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/Tag__Text.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/schemas/Schema__Html_Document.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/schemas/Schema__Html_Node__Data__Type.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/html/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/actions/LLM_Request__Execute.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/actions/Type_Safe__Schema_For__LLMs.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/actions/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder__Open_AI.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/builders/LLM_Request__Factory.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/builders/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/LLM_Cache__Path_Generator.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__File_System.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/LLM_Request__Cache__Storage.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Local__Folder.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/Virtual_Storage__Sqlite.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/cache/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/platforms/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/platforms/open_ai/API__LLM__Open_AI.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/platforms/open_ai/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Cache__Index.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Function_Call.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Content.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Request__Message__Role.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/Schema__LLM_Response__Cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/Event__Queue.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/PubSub__Client.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/PubSub__Room.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/PubSub__Server.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/PubSub__Sqlite.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Execute_Method.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/python_compatibility/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/python_compatibility/python_3_8.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_float/Safe_Float.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_float/Safe_Float__Engineering.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_float/Safe_Float__Money.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_float/Safe_Float__Percentage_Exact.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_float/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_Int.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_UInt.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_UInt__Byte.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_UInt__FileSize.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_UInt__Percentage.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/Safe_UInt__Port.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_int/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Name.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__File__Path.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__Hash.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__Text.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__Text__Dangerous.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/Safe_Str__Url.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Html.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Content_Type.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__ETag.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Last_Modified.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/Safe_Str__Http__Text.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/safe_str/http/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Cursor.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Database.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Field.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Globals.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Table.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Schema__Table__Requests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Patch.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Sqlite.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Sqlite__Cache__Requests__Table.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/Sqlite__DB__Requests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/TestCase__Sqlite__Cache__Requests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/cache/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/models/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SCP.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Cache__Requests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Execute.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Health_Check.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Linux.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Linux__Amazon.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/SSH__Python.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/TestCase__SSH.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/ssh/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Config.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Handler.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Stack.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__Stats.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Call__View_Model.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/Trace_Files.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/trace/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__Attribute.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__Element.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__File.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__File__Load.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__File__To_Dict.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/Xml__File__To_Xml.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Channel.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Enclosure.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Feed.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Feed__Parser.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Image.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/xml/rss/RSS__Item.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Catch.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Custom_Handler_For_Http_Tests.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Hook_Method.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Log_To_Queue.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Log_To_String.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Logging.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Patch_Print.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Profiler.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Pytest.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Stderr.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Stdout.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Env_Vars.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_File.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Folder.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Sys_Path.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Web_Server.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Zip.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Temp_Zip_In_Memory.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Unit_Test.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/Unzip_File.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/performance/Performance_Measure__Session.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/performance/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Measurement.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/performance/models/Model__Performance_Measure__Result.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/testing/performance/models/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Base.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Dict.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__List.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Method.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Primitive.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Set.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/Type_Safe__Tuple.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/decorators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/decorators/type_safe.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/methods/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/methods/type_safe_property.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Annotations.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Convert.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Json_Compressor__Type_Registry.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/Type_Safe__Validation.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/shared/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/Type_Safe__Validator.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/Validator__Max.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/Validator__Min.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/Validator__One_Of.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/Validator__Regex.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/validators/__init__.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Assert.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Call_Stack.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Csv.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Dev.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Env.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Exceptions.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Files.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Functions.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Http.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Int.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Json.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Json_Cache.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Lists.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Misc.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Objects.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Png.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Process.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Python_Logger.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Regex.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Status.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Str.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Threads.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Toml.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Version.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/utils/Zip.py +0 -0
- {osbot_utils-2.67.0 → osbot_utils-2.69.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.
|
3
|
+
Version: 2.69.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
|
-

|
27
27
|
[](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
|
-

|
6
6
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
7
7
|
|
8
8
|
|
@@ -0,0 +1,112 @@
|
|
1
|
+
from osbot_utils.helpers.html.Html__To__Html_Dict import STRING__SCHEMA_TEXT, STRING__SCHEMA_NODES
|
2
|
+
|
3
|
+
HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta',
|
4
|
+
'param', 'source', 'track', 'wbr'}
|
5
|
+
HTML_DEFAULT_DOCTYPE_VALUE = "<!DOCTYPE html>\n"
|
6
|
+
|
7
|
+
|
8
|
+
class Html_Dict__To__Html:
|
9
|
+
def __init__(self, root, # Root element dictionary
|
10
|
+
include_doctype=True, # Whether to include DOCTYPE
|
11
|
+
doctype=HTML_DEFAULT_DOCTYPE_VALUE # DOCTYPE string to use
|
12
|
+
):
|
13
|
+
self.self_closing_tags = HTML_SELF_CLOSING_TAGS
|
14
|
+
self.root = root
|
15
|
+
self.include_doctype = include_doctype
|
16
|
+
self.doctype = doctype
|
17
|
+
|
18
|
+
def convert(self): # Convert dictionary to HTML string
|
19
|
+
if not self.root:
|
20
|
+
return ""
|
21
|
+
|
22
|
+
html = self.convert_element(self.root, 0)
|
23
|
+
|
24
|
+
if self.include_doctype and self.root.get("tag") == "html": # Only add DOCTYPE for html root
|
25
|
+
return self.doctype + html
|
26
|
+
return html
|
27
|
+
|
28
|
+
def convert_attrs(self, attrs): # Convert attributes dict to HTML string
|
29
|
+
if not attrs:
|
30
|
+
return ""
|
31
|
+
|
32
|
+
attrs_str_parts = []
|
33
|
+
|
34
|
+
for key, value in attrs.items(): # Preserve original order
|
35
|
+
if value is None:
|
36
|
+
attr_str = f'{key}'
|
37
|
+
elif value == "": # Handle empty string values
|
38
|
+
attr_str = f'{key}=""'
|
39
|
+
elif '"' in str(value) and "'" in str(value): # Both quotes present
|
40
|
+
escaped_value = str(value).replace('"', '"')
|
41
|
+
attr_str = f'{key}="{escaped_value}"'
|
42
|
+
elif '"' in str(value): # Use single quotes if double quotes present
|
43
|
+
attr_str = f"{key}='{value}'"
|
44
|
+
else:
|
45
|
+
attr_str = f'{key}="{value}"'
|
46
|
+
attrs_str_parts.append(attr_str)
|
47
|
+
|
48
|
+
attrs_str = ' '.join(attrs_str_parts)
|
49
|
+
return f" {attrs_str}" if attrs_str else ""
|
50
|
+
|
51
|
+
def convert_element(self, element, # Element dictionary to convert
|
52
|
+
indent_level # Current indentation level
|
53
|
+
):
|
54
|
+
if element.get("type") == STRING__SCHEMA_TEXT:
|
55
|
+
return element.get("data", "")
|
56
|
+
|
57
|
+
tag = element.get("tag")
|
58
|
+
attrs = element.get("attrs", {})
|
59
|
+
nodes = element.get(STRING__SCHEMA_NODES, [])
|
60
|
+
|
61
|
+
if not tag: # Safety check
|
62
|
+
return ""
|
63
|
+
|
64
|
+
attrs_str = self.convert_attrs(attrs)
|
65
|
+
indent = " " * indent_level
|
66
|
+
|
67
|
+
# Special handling for void elements
|
68
|
+
if tag in self.self_closing_tags:
|
69
|
+
if nodes: # Void elements shouldn't have content
|
70
|
+
print(f"Warning: void element <{tag}> has child nodes")
|
71
|
+
return f"{indent}<{tag}{attrs_str} />\n"
|
72
|
+
|
73
|
+
# Start building the HTML
|
74
|
+
html = f"{indent}<{tag}{attrs_str}>"
|
75
|
+
|
76
|
+
# Analyze content type
|
77
|
+
has_text_nodes = any(node.get("type") == STRING__SCHEMA_TEXT for node in nodes)
|
78
|
+
has_element_nodes = any(node.get("type") != STRING__SCHEMA_TEXT for node in nodes)
|
79
|
+
|
80
|
+
# Determine formatting strategy
|
81
|
+
if not nodes: # Empty element
|
82
|
+
html += f"</{tag}>\n"
|
83
|
+
elif has_element_nodes and not has_text_nodes: # Only element children
|
84
|
+
html += "\n"
|
85
|
+
html += self.convert_children(nodes, indent_level + 1)
|
86
|
+
html += f"{indent}</{tag}>\n"
|
87
|
+
elif has_text_nodes and not has_element_nodes: # Only text content
|
88
|
+
html += self.convert_children(nodes, indent_level + 1)
|
89
|
+
html += f"</{tag}>\n"
|
90
|
+
else: # Mixed content
|
91
|
+
# For mixed content, don't add extra formatting
|
92
|
+
for node in nodes:
|
93
|
+
if node.get("type") == STRING__SCHEMA_TEXT:
|
94
|
+
html += node.get("data", "")
|
95
|
+
else:
|
96
|
+
# Recursively convert child elements with no indentation
|
97
|
+
child_html = self.convert_element(node, 0)
|
98
|
+
# Remove the trailing newline from child elements in mixed content
|
99
|
+
if child_html.endswith('\n'):
|
100
|
+
child_html = child_html[:-1]
|
101
|
+
html += child_html
|
102
|
+
html += f"</{tag}>\n"
|
103
|
+
|
104
|
+
return html
|
105
|
+
|
106
|
+
def convert_children(self, nodes, # List of child nodes
|
107
|
+
indent_level # Current indentation level
|
108
|
+
):
|
109
|
+
html = ""
|
110
|
+
for node in nodes:
|
111
|
+
html += self.convert_element(node, indent_level)
|
112
|
+
return html
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from typing import Dict, Any
|
2
|
+
from osbot_utils.helpers.html.Html__To__Html_Dict import STRING__SCHEMA_TEXT, STRING__SCHEMA_NODES
|
3
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Document import Schema__Html_Document
|
4
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Node import Schema__Html_Node
|
5
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Node__Data import Schema__Html_Node__Data
|
6
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Node__Data__Type import Schema__Html_Node__Data__Type
|
7
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
8
|
+
|
9
|
+
class Html_Dict__To__Html_Document(Type_Safe):
|
10
|
+
html__dict : dict = None
|
11
|
+
html__document: Schema__Html_Document = None
|
12
|
+
|
13
|
+
def convert(self):
|
14
|
+
self.html__document = self.parse_html_dict(self.html__dict)
|
15
|
+
return self.html__document
|
16
|
+
|
17
|
+
def parse_html_dict(self, target: Dict[str, Any]) -> Schema__Html_Document:
|
18
|
+
if not target or not isinstance(target, dict):
|
19
|
+
raise ValueError("Invalid HTML dictionary structure")
|
20
|
+
|
21
|
+
root_node = self.parse_node(target, position=-1) # Root has position -1
|
22
|
+
return Schema__Html_Document(root_node=root_node)
|
23
|
+
|
24
|
+
def parse_node(self, target: Dict[str, Any], position: int) -> Schema__Html_Node: # Parse a node and separate child nodes from text nodes with positions
|
25
|
+
|
26
|
+
if target.get('type') == STRING__SCHEMA_TEXT: # This shouldn't happen at this level since we're parsing element nodes
|
27
|
+
raise ValueError("Unexpected text node at element level")
|
28
|
+
|
29
|
+
|
30
|
+
child_nodes = [] # Create lists for child nodes and text nodes
|
31
|
+
text_nodes = []
|
32
|
+
|
33
|
+
|
34
|
+
nodes_list = target.get(STRING__SCHEMA_NODES, []) # Process all nodes and assign positions
|
35
|
+
for idx, node in enumerate(nodes_list):
|
36
|
+
if node.get('type') == STRING__SCHEMA_TEXT: # Create text node with position
|
37
|
+
text_node = Schema__Html_Node__Data(data = node.get('data', '') ,
|
38
|
+
type = Schema__Html_Node__Data__Type.TEXT,
|
39
|
+
position = idx )
|
40
|
+
text_nodes.append(text_node)
|
41
|
+
else:
|
42
|
+
child_node = self.parse_node(node, position=idx) # Create element node with position
|
43
|
+
child_nodes.append(child_node)
|
44
|
+
|
45
|
+
return Schema__Html_Node(attrs = target.get('attrs', {}), # Create the element node with separated lists
|
46
|
+
child_nodes = child_nodes ,
|
47
|
+
text_nodes = text_nodes ,
|
48
|
+
tag = target.get('tag' , ''),
|
49
|
+
position = position )
|
@@ -0,0 +1,147 @@
|
|
1
|
+
from osbot_utils.helpers.html.Html_Dict__To__Html import HTML_SELF_CLOSING_TAGS
|
2
|
+
from osbot_utils.helpers.html.Html__To__Html_Dict import STRING__SCHEMA_TEXT, STRING__SCHEMA_NODES
|
3
|
+
from osbot_utils.helpers.html.Tag__Base import Tag__Base
|
4
|
+
from osbot_utils.helpers.html.Tag__Body import Tag__Body
|
5
|
+
from osbot_utils.helpers.html.Tag__Head import Tag__Head
|
6
|
+
from osbot_utils.helpers.html.Tag__Html import Tag__Html
|
7
|
+
from osbot_utils.helpers.html.Tag__Link import Tag__Link
|
8
|
+
from osbot_utils.helpers.html.Tag__Text import Tag__Text
|
9
|
+
|
10
|
+
|
11
|
+
class Html_Dict__To__Html_Tags:
|
12
|
+
|
13
|
+
def __init__(self, root):
|
14
|
+
self.root = root
|
15
|
+
|
16
|
+
def convert(self):
|
17
|
+
return self.convert_element(self.root)
|
18
|
+
|
19
|
+
def convert_element(self, element):
|
20
|
+
tag_name = element.get("tag")
|
21
|
+
|
22
|
+
|
23
|
+
if tag_name == 'html': # Handle special tag types with dedicated conversion methods
|
24
|
+
return self.convert_to__tag__html(element)
|
25
|
+
elif tag_name == 'head':
|
26
|
+
return self.convert_to__tag__head(element, 0) # Default indent 0
|
27
|
+
elif tag_name == 'link':
|
28
|
+
return self.convert_to__tag__link(element)
|
29
|
+
else: # 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): # Extract all text from an element's text node nodes.
|
33
|
+
inner_text = ""
|
34
|
+
for node in element.get(STRING__SCHEMA_NODES, []):
|
35
|
+
if node.get("type") == STRING__SCHEMA_TEXT:
|
36
|
+
inner_text += node.get("data", "")
|
37
|
+
return inner_text
|
38
|
+
|
39
|
+
def convert_to__tag(self, target_tag, element, indent):
|
40
|
+
if element.get("type") == STRING__SCHEMA_TEXT: # Handle text nodes directly
|
41
|
+
return Tag__Text(element.get("data", ""))
|
42
|
+
|
43
|
+
tag_name = element.get("tag")
|
44
|
+
attrs = element.get("attrs", {})
|
45
|
+
nodes = element.get(STRING__SCHEMA_NODES, [])
|
46
|
+
end_tag = tag_name not in HTML_SELF_CLOSING_TAGS
|
47
|
+
tag_indent = indent + 1
|
48
|
+
|
49
|
+
node_positions = [] # Create node lists with position tracking
|
50
|
+
|
51
|
+
for idx, node in enumerate(nodes): # Process all nodes and track their positions
|
52
|
+
if node.get("type") == STRING__SCHEMA_TEXT:
|
53
|
+
text_obj = Tag__Text(node.get("data", "")) # Create text node with position info
|
54
|
+
node_positions.append((idx, 'text', text_obj))
|
55
|
+
else:
|
56
|
+
child_tag = self.convert_to__tag(Tag__Base, node, tag_indent) # Create element node
|
57
|
+
node_positions.append((idx, 'element', child_tag))
|
58
|
+
|
59
|
+
node_positions.sort(key=lambda x: x[0]) # Sort by position (though they should already be in order)
|
60
|
+
|
61
|
+
|
62
|
+
inner_html = "" # Collect consecutive text nodes at the beginning for inner_html
|
63
|
+
first_element_idx = None
|
64
|
+
|
65
|
+
for idx, (pos, node_type, node_obj) in enumerate(node_positions):
|
66
|
+
if node_type == 'element':
|
67
|
+
first_element_idx = idx
|
68
|
+
break
|
69
|
+
else:
|
70
|
+
inner_html += node_obj.data
|
71
|
+
|
72
|
+
|
73
|
+
if first_element_idx is None: # If all nodes are text, use them all as inner_html
|
74
|
+
inner_html = "".join(n[2].data for n in node_positions if n[1] == 'text')
|
75
|
+
elements = []
|
76
|
+
else:
|
77
|
+
inner_html = "".join(n[2].data for i, n in enumerate(node_positions) # Only use text before first element as inner_html
|
78
|
+
if n[1] == 'text' and i < first_element_idx)
|
79
|
+
elements = [n[2] for i, n in enumerate(node_positions) if i >= first_element_idx] # All nodes go into elements (including remaining text nodes)
|
80
|
+
|
81
|
+
tag_kwargs = dict(tag_name = tag_name ,
|
82
|
+
attributes = attrs ,
|
83
|
+
end_tag = end_tag ,
|
84
|
+
indent = tag_indent,
|
85
|
+
inner_html = inner_html)
|
86
|
+
tag = target_tag(**tag_kwargs)
|
87
|
+
tag.elements = elements
|
88
|
+
|
89
|
+
return tag
|
90
|
+
|
91
|
+
def convert_to__tag__head(self, element, indent):
|
92
|
+
attrs = element.get("attrs", {})
|
93
|
+
nodes = element.get(STRING__SCHEMA_NODES, [])
|
94
|
+
head_indent = indent + 1
|
95
|
+
tag_head = Tag__Head(indent=head_indent, **attrs)
|
96
|
+
|
97
|
+
for node in nodes:
|
98
|
+
tag_name = node.get("tag")
|
99
|
+
|
100
|
+
if tag_name == 'title':
|
101
|
+
tag_head.title = self.collect_inner_text(node) # Extract title text from text node nodes
|
102
|
+
elif tag_name == 'link':
|
103
|
+
tag_head.links.append(self.convert_to__tag__link(node))
|
104
|
+
elif tag_name == 'meta':
|
105
|
+
tag_head.elements.append(self.convert_to__tag(Tag__Base, node, head_indent))
|
106
|
+
elif tag_name == 'style':
|
107
|
+
style_element = self.convert_to__tag(Tag__Base, node, head_indent) # For style tags, collect the CSS content from text nodes
|
108
|
+
tag_head.elements.append(style_element)
|
109
|
+
else:
|
110
|
+
tag_head.elements.append(self.convert_to__tag(Tag__Base, node, head_indent)) # Handle any other head elements
|
111
|
+
|
112
|
+
return tag_head
|
113
|
+
|
114
|
+
def convert_to__tag__html(self, element):
|
115
|
+
attrs = element.get("attrs", {})
|
116
|
+
nodes = element.get(STRING__SCHEMA_NODES, [])
|
117
|
+
lang = attrs.get("lang")
|
118
|
+
|
119
|
+
tag_html = Tag__Html(attributes=attrs, lang=lang, doc_type=False)
|
120
|
+
|
121
|
+
head_found = False # Initialize head and body if not found
|
122
|
+
body_found = False
|
123
|
+
|
124
|
+
for node in nodes:
|
125
|
+
tag_name = node.get("tag")
|
126
|
+
|
127
|
+
if tag_name == 'head':
|
128
|
+
tag_html.head = self.convert_to__tag__head(node, tag_html.indent)
|
129
|
+
head_found = True
|
130
|
+
elif tag_name == 'body':
|
131
|
+
tag_html.body = self.convert_to__tag(Tag__Body, node, tag_html.indent)
|
132
|
+
body_found = True
|
133
|
+
else:
|
134
|
+
print(f'Unexpected child of html tag: {tag_name}') # Log unexpected child elements of html
|
135
|
+
|
136
|
+
if not head_found: # Handle missing head or body (required for valid HTML structure)
|
137
|
+
tag_html.head = Tag__Head(indent=tag_html.indent + 1)
|
138
|
+
|
139
|
+
if not body_found:
|
140
|
+
tag_html.body = Tag__Body(indent=tag_html.indent + 1)
|
141
|
+
|
142
|
+
return tag_html
|
143
|
+
|
144
|
+
def convert_to__tag__link(self, element):
|
145
|
+
attrs = element.get("attrs", {})
|
146
|
+
tag_link = Tag__Link(**attrs)
|
147
|
+
return tag_link
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from typing import Dict, Any, List, Union
|
2
|
+
from osbot_utils.helpers.html.Html__To__Html_Dict import STRING__SCHEMA_TEXT, STRING__SCHEMA_NODES, STRING__SCHEMA_TAG, STRING__SCHEMA_ATTRS
|
3
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Document import Schema__Html_Document
|
4
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Node import Schema__Html_Node
|
5
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
6
|
+
|
7
|
+
|
8
|
+
class Html_Document__To__Html_Dict(Type_Safe):
|
9
|
+
html__document : Schema__Html_Document = None
|
10
|
+
html__dict : dict = None
|
11
|
+
|
12
|
+
def convert(self) -> dict: # Convert Schema__Html_Document back to html dict format
|
13
|
+
if not self.html__document:
|
14
|
+
raise ValueError("No document to convert")
|
15
|
+
|
16
|
+
self.html__dict = self.node_to_dict(self.html__document.root_node)
|
17
|
+
return self.html__dict
|
18
|
+
|
19
|
+
def node_to_dict(self, node: Schema__Html_Node) -> Dict[str, Any]: # Convert a Schema__Html_Node back to dict format, merging child and text nodes by position
|
20
|
+
|
21
|
+
result = { STRING__SCHEMA_TAG : node.tag, # Create the basic dict structure
|
22
|
+
STRING__SCHEMA_ATTRS : node.attrs,
|
23
|
+
STRING__SCHEMA_NODES : []}
|
24
|
+
|
25
|
+
all_nodes = [] # Merge child_nodes and text_nodes back together based on position
|
26
|
+
|
27
|
+
for child in node.child_nodes: # Add child nodes with their positions
|
28
|
+
all_nodes.append((child.position, 'child', child))
|
29
|
+
|
30
|
+
for text in node.text_nodes: # Add text nodes with their positions
|
31
|
+
all_nodes.append((text.position, 'text', text))
|
32
|
+
|
33
|
+
all_nodes.sort(key=lambda x: x[0]) # Sort by position
|
34
|
+
|
35
|
+
for position, node_type, node_obj in all_nodes: # Build the nodes list in the correct order
|
36
|
+
if node_type == 'text':
|
37
|
+
text_dict = { 'type': STRING__SCHEMA_TEXT, # Convert text node to dict
|
38
|
+
'data': node_obj.data }
|
39
|
+
result[STRING__SCHEMA_NODES].append(text_dict)
|
40
|
+
else:
|
41
|
+
child_dict = self.node_to_dict(node_obj) # Recursively convert child node
|
42
|
+
result[STRING__SCHEMA_NODES].append(child_dict)
|
43
|
+
|
44
|
+
return result
|
@@ -1,8 +1,11 @@
|
|
1
1
|
from html.parser import HTMLParser
|
2
2
|
|
3
3
|
HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
|
4
|
-
|
4
|
+
STRING__SCHEMA_ATTRS = 'attrs'
|
5
5
|
STRING__SCHEMA_NODES = 'nodes'
|
6
|
+
STRING__SCHEMA_TEXT = 'TEXT'
|
7
|
+
STRING__SCHEMA_TAG = 'tag'
|
8
|
+
|
6
9
|
STRING__DATA_TEXT = f'{STRING__SCHEMA_TEXT}:'
|
7
10
|
|
8
11
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from typing import List, Dict, Optional
|
2
|
+
from osbot_utils.helpers.html.schemas.Schema__Html_Node__Data import Schema__Html_Node__Data
|
3
|
+
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
4
|
+
|
5
|
+
|
6
|
+
class Schema__Html_Node(Type_Safe):
|
7
|
+
attrs : Dict[str, str ] # HTML attributes (e.g., {'class': 'container'})
|
8
|
+
child_nodes : List['Schema__Html_Node'] # Element nodes only
|
9
|
+
text_nodes : List[Schema__Html_Node__Data] # Text nodes only
|
10
|
+
tag : str # HTML tag name (e.g., 'div', 'meta', 'title')
|
11
|
+
position : int = -1 # Position in parent's nodes list (-1 for root)
|
12
|
+
|
@@ -4,3 +4,4 @@ from osbot_utils.type_safe.Type_Safe import Type_
|
|
4
4
|
class Schema__Html_Node__Data(Type_Safe):
|
5
5
|
data : str # Text content
|
6
6
|
type : Schema__Html_Node__Data__Type = Schema__Html_Node__Data__Type.TEXT # Always 'text' for text nodes
|
7
|
+
position : int # Position in parent's nodes list
|
{osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/helpers/llms/builders/LLM_Request__Builder.py
RENAMED
@@ -1,5 +1,6 @@
|
|
1
1
|
from typing import Dict, Any, Type
|
2
2
|
from osbot_utils.helpers.llms.actions.Type_Safe__Schema_For__LLMs import Type_Safe__Schema_For__LLMs
|
3
|
+
from osbot_utils.helpers.llms.schemas.Safe_Str__LLM__Model_Name import Safe_Str__LLM__Model_Name
|
3
4
|
from osbot_utils.helpers.llms.schemas.Schema__LLM_Request import Schema__LLM_Request
|
4
5
|
from osbot_utils.helpers.llms.schemas.Schema__LLM_Request__Data import Schema__LLM_Request__Data
|
5
6
|
from osbot_utils.helpers.llms.schemas.Schema__LLM_Request__Function_Call import Schema__LLM_Request__Function_Call
|
@@ -40,14 +41,14 @@ class LLM_Request__Builder(Type_Safe):
|
|
40
41
|
self.llm_request_data.function_call = function_call
|
41
42
|
return self
|
42
43
|
|
43
|
-
def set__model (self, model :
|
44
|
-
def set__platform (self, platform: Safe_Str__Text): self.llm_request_data.platform = platform; return self
|
45
|
-
def set__provider (self, provider: Safe_Str__Text): self.llm_request_data.provider = provider; return self
|
46
|
-
def set__model__gpt_4o (self
|
47
|
-
def set__model__gpt_4o_mini (self
|
48
|
-
def set__model__gpt_4_1 (self
|
49
|
-
def set__model__gpt_4_1_mini(self
|
50
|
-
def set__model__gpt_4_1_nano(self
|
44
|
+
def set__model (self, model : Safe_Str__LLM__Model_Name): self.llm_request_data.model = model ; return self
|
45
|
+
def set__platform (self, platform: Safe_Str__Text ): self.llm_request_data.platform = platform; return self
|
46
|
+
def set__provider (self, provider: Safe_Str__Text ): self.llm_request_data.provider = provider; return self
|
47
|
+
def set__model__gpt_4o (self ): return self.set__model('gpt-4o' )
|
48
|
+
def set__model__gpt_4o_mini (self ): return self.set__model('gpt-4o-mini' )
|
49
|
+
def set__model__gpt_4_1 (self ): return self.set__model('gpt-4.1' )
|
50
|
+
def set__model__gpt_4_1_mini(self ): return self.set__model('gpt-4.1-mini')
|
51
|
+
def set__model__gpt_4_1_nano(self ): return self.set__model('gpt-4.1-nano')
|
51
52
|
|
52
53
|
|
53
54
|
@type_safe
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
from osbot_utils.helpers.safe_str.Safe_Str import Safe_Str
|
4
|
+
|
5
|
+
TYPE_SAFE_STR__LLM__MODEL_NAME__MAX_LENGTH = 256
|
6
|
+
TYPE_SAFE_STR__LLM__MODEL_NAME__REGEX = r'[^a-zA-Z0-9/_\-.:]'
|
7
|
+
|
8
|
+
class Safe_Str__LLM__Model_Name(Safe_Str):
|
9
|
+
regex = re.compile(TYPE_SAFE_STR__LLM__MODEL_NAME__REGEX)
|
10
|
+
max_length = TYPE_SAFE_STR__LLM__MODEL_NAME__MAX_LENGTH
|
@@ -1,11 +1,12 @@
|
|
1
1
|
from typing import List, Optional
|
2
|
+
from osbot_utils.helpers.llms.schemas.Safe_Str__LLM__Model_Name import Safe_Str__LLM__Model_Name
|
2
3
|
from osbot_utils.helpers.llms.schemas.Schema__LLM_Request__Function_Call import Schema__LLM_Request__Function_Call
|
3
4
|
from osbot_utils.helpers.llms.schemas.Schema__LLM_Request__Message__Content import Schema__LLM_Request__Message__Content
|
4
5
|
from osbot_utils.helpers.safe_str.Safe_Str__Text import Safe_Str__Text
|
5
6
|
from osbot_utils.type_safe.Type_Safe import Type_Safe
|
6
7
|
|
7
8
|
class Schema__LLM_Request__Data(Type_Safe): # Schema for LLM API request data
|
8
|
-
model :
|
9
|
+
model : Safe_Str__LLM__Model_Name # LLM model identifier
|
9
10
|
platform : Safe_Str__Text
|
10
11
|
provider : Safe_Str__Text
|
11
12
|
messages : List [Schema__LLM_Request__Message__Content] # Message content entries
|
@@ -6,8 +6,6 @@ from osbot_utils.type_safe.shared.Type_Safe__Shared__Variables import IMMUTABL
|
|
6
6
|
from osbot_utils.type_safe.shared.Type_Safe__Validation import type_safe_validation
|
7
7
|
from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Value import type_safe_step_default_value
|
8
8
|
|
9
|
-
|
10
|
-
|
11
9
|
class Type_Safe__Step__Class_Kwargs: # Handles class-level keyword arguments processing
|
12
10
|
|
13
11
|
type_safe_cache : Type_Safe__Cache # Cache component reference
|
{osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py
RENAMED
@@ -26,7 +26,7 @@ if sys.version_info < (3, 8): # pragma
|
|
26
26
|
else:
|
27
27
|
return ()
|
28
28
|
else:
|
29
|
-
from typing import get_args, Any
|
29
|
+
from typing import get_args, Any, ForwardRef
|
30
30
|
|
31
31
|
|
32
32
|
class Type_Safe__Step__From_Json:
|
@@ -83,6 +83,10 @@ class Type_Safe__Step__From_Json:
|
|
83
83
|
expected_type = get_args(attribute_annotation)[0] # get the first arg (which is the type)
|
84
84
|
type_safe_list = Type_Safe__List(expected_type) # create a new instance of Type_Safe__List
|
85
85
|
if value:
|
86
|
+
if isinstance(expected_type, ForwardRef): # Check if it's a self-reference
|
87
|
+
forward_name = expected_type.__forward_arg__
|
88
|
+
if forward_name == _self.__class__.__name__:
|
89
|
+
expected_type = _self.__class__
|
86
90
|
for item in value: # next we need to convert all items (to make sure they all match the type)
|
87
91
|
if type(item) is dict:
|
88
92
|
new_item = expected_type(**item) # create new object
|
{osbot_utils-2.67.0 → osbot_utils-2.69.0}/osbot_utils/type_safe/steps/Type_Safe__Step__Init.py
RENAMED
@@ -1,4 +1,5 @@
|
|
1
1
|
from enum import EnumMeta
|
2
|
+
from typing import ForwardRef
|
2
3
|
from osbot_utils.type_safe.shared.Type_Safe__Annotations import type_safe_annotations
|
3
4
|
from osbot_utils.type_safe.steps.Type_Safe__Step__Default_Value import type_safe_step_default_value, get_args
|
4
5
|
|
@@ -27,7 +28,7 @@ class Type_Safe__Step__Init:
|
|
27
28
|
raise ValueError(f"{__self.__class__.__name__} has no attribute '{key}' and cannot be assigned the value '{value}'. "
|
28
29
|
f"Use {__self.__class__.__name__}.__default_kwargs__() see what attributes are available") from None
|
29
30
|
|
30
|
-
def convert_value_to_type_safe_objects(self, __self, key, value):
|
31
|
+
def convert_value_to_type_safe_objects(self, __self, key, value): # todo: see if we should use _self here (like in Type_Safe__Step__From_Json, or vice versa)
|
31
32
|
annotation = type_safe_annotations.obj_attribute_annotation(__self, key)
|
32
33
|
if annotation:
|
33
34
|
if isinstance(annotation, EnumMeta) and type(value) is str:
|
@@ -47,6 +48,10 @@ class Type_Safe__Step__Init:
|
|
47
48
|
elif origin is list and isinstance(value, list):
|
48
49
|
from osbot_utils.type_safe.Type_Safe__List import Type_Safe__List
|
49
50
|
item_type = get_args(annotation)[0]
|
51
|
+
if isinstance(item_type, ForwardRef):
|
52
|
+
forward_name = item_type.__forward_arg__
|
53
|
+
if forward_name == __self.__class__.__name__:
|
54
|
+
item_type = __self.__class__
|
50
55
|
type_safe_list = Type_Safe__List(expected_type=item_type)
|
51
56
|
for item in value:
|
52
57
|
type_safe_list.append(item)
|
@@ -0,0 +1 @@
|
|
1
|
+
v2.69.0
|
@@ -1,97 +0,0 @@
|
|
1
|
-
from osbot_utils.helpers.html.Html__To__Html_Dict import STRING__SCHEMA_TEXT, STRING__SCHEMA_NODES
|
2
|
-
|
3
|
-
HTML_SELF_CLOSING_TAGS = {'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'}
|
4
|
-
HTML_DEFAULT_DOCTYPE_VALUE = "<!DOCTYPE html>\n"
|
5
|
-
|
6
|
-
class Html_Dict__To__Html:
|
7
|
-
def __init__(self, root, include_doctype=True, doctype=HTML_DEFAULT_DOCTYPE_VALUE):
|
8
|
-
self.self_closing_tags = HTML_SELF_CLOSING_TAGS # Define a list of self-closing tags
|
9
|
-
self.root = root
|
10
|
-
self.include_doctype = include_doctype
|
11
|
-
self.doctype = doctype
|
12
|
-
|
13
|
-
def convert(self):
|
14
|
-
html = self.convert_element(self.root, 0)
|
15
|
-
if self.include_doctype:
|
16
|
-
return self.doctype + html
|
17
|
-
return html
|
18
|
-
|
19
|
-
def convert_attrs(self, attrs):
|
20
|
-
attrs_str_parts = [] # List to hold each attribute's string representation
|
21
|
-
for key, value in attrs.items():
|
22
|
-
if value is None: # Handle None values
|
23
|
-
attr_str = f'{key}'
|
24
|
-
elif '"' in str(value): # Check if the attribute value contains double quotes
|
25
|
-
escaped_value = """.join(str(value).split("\"")) # If so, escape double quotes and format the attribute string
|
26
|
-
attr_str = f'{key}="{escaped_value}"'
|
27
|
-
else:
|
28
|
-
attr_str = f'{key}="{value}"' # If not, simply format the attribute string
|
29
|
-
attrs_str_parts.append(attr_str)
|
30
|
-
|
31
|
-
attrs_str = ' '.join(attrs_str_parts) # Join the parts into the final attributes string
|
32
|
-
|
33
|
-
if attrs_str:
|
34
|
-
attrs_str = " " + attrs_str # Prepend a space if there are attributes
|
35
|
-
return attrs_str
|
36
|
-
|
37
|
-
def convert_element(self, element, indent_level):
|
38
|
-
"""Recursively converts a dictionary to an HTML string with indentation."""
|
39
|
-
# Check if this is a text node
|
40
|
-
if element.get("type") == STRING__SCHEMA_TEXT:
|
41
|
-
return element.get("data", "") # Return text content directly for text nodes
|
42
|
-
|
43
|
-
tag = element.get("tag")
|
44
|
-
attrs = element.get("attrs", {})
|
45
|
-
nodes = element.get(STRING__SCHEMA_NODES, [])
|
46
|
-
|
47
|
-
attrs_str = self.convert_attrs(attrs) # Convert attributes dictionary to a string
|
48
|
-
indent = " " * indent_level # Indentation for the current level, assuming 4 spaces per indent level
|
49
|
-
|
50
|
-
# Handle self-closing tags
|
51
|
-
if tag in self.self_closing_tags and not nodes: # Check if the tag is self-closing and has no nodes
|
52
|
-
return f"{indent}<{tag}{attrs_str} />\n"
|
53
|
-
|
54
|
-
# Start building the HTML
|
55
|
-
html = f"{indent}<{tag}{attrs_str}>" # Opening tag with indentation
|
56
|
-
|
57
|
-
# Separate nodes into text nodes and element nodes
|
58
|
-
text_nodes = [node for node in nodes if node.get("type") == STRING__SCHEMA_TEXT]
|
59
|
-
element_nodes = [node for node in nodes if node.get("type") != STRING__SCHEMA_TEXT]
|
60
|
-
|
61
|
-
# If there are only element nodes, add a newline after the opening tag
|
62
|
-
if element_nodes and not text_nodes:
|
63
|
-
html += "\n"
|
64
|
-
|
65
|
-
# Process nodes, maintaining the original order but with proper formatting
|
66
|
-
if nodes:
|
67
|
-
# Track if we're currently in a text section or element section
|
68
|
-
# This helps us add newlines only between elements, not text
|
69
|
-
previous_was_element = False
|
70
|
-
|
71
|
-
for node in nodes:
|
72
|
-
if node.get("type") == STRING__SCHEMA_TEXT:
|
73
|
-
# Text node - directly append content
|
74
|
-
html += node.get("data", "")
|
75
|
-
previous_was_element = False
|
76
|
-
else:
|
77
|
-
# Element node - format with proper indentation
|
78
|
-
if previous_was_element:
|
79
|
-
# If previous child was also an element, we may already have a newline
|
80
|
-
if not html.endswith("\n"):
|
81
|
-
html += "\n"
|
82
|
-
|
83
|
-
html += self.convert_element(node, indent_level + 1)
|
84
|
-
previous_was_element = True
|
85
|
-
|
86
|
-
# Handle closing tag based on content
|
87
|
-
if element_nodes and not text_nodes:
|
88
|
-
# If only element nodes, add indented closing tag
|
89
|
-
html += f"{indent}</{tag}>\n"
|
90
|
-
elif nodes: # Any type of nodes
|
91
|
-
# If mixed content or only text, add closing tag without indentation
|
92
|
-
html += f"</{tag}>\n"
|
93
|
-
else:
|
94
|
-
# Empty tag, replace with self-contained format
|
95
|
-
html = f"{indent}<{tag}{attrs_str}></{tag}>\n"
|
96
|
-
|
97
|
-
return html
|