osbot-utils 1.7.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. osbot_utils/__init__.py +1 -0
  2. osbot_utils/base_classes/Cache_Pickle.py +129 -0
  3. osbot_utils/base_classes/Kwargs_To_Disk.py +27 -0
  4. osbot_utils/base_classes/Kwargs_To_Self.py +308 -0
  5. osbot_utils/base_classes/Type_Safe__List.py +14 -0
  6. osbot_utils/base_classes/__init__.py +0 -0
  7. osbot_utils/context_managers/__init__.py +0 -0
  8. osbot_utils/context_managers/capture_duration.py +33 -0
  9. osbot_utils/decorators/__init__.py +0 -0
  10. osbot_utils/decorators/classes/__init__.py +0 -0
  11. osbot_utils/decorators/classes/singleton.py +9 -0
  12. osbot_utils/decorators/lists/__init__.py +0 -0
  13. osbot_utils/decorators/lists/filter_list.py +12 -0
  14. osbot_utils/decorators/lists/group_by.py +21 -0
  15. osbot_utils/decorators/lists/index_by.py +27 -0
  16. osbot_utils/decorators/methods/__init__.py +0 -0
  17. osbot_utils/decorators/methods/cache.py +19 -0
  18. osbot_utils/decorators/methods/cache_on_function.py +56 -0
  19. osbot_utils/decorators/methods/cache_on_self.py +78 -0
  20. osbot_utils/decorators/methods/cache_on_tmp.py +71 -0
  21. osbot_utils/decorators/methods/capture_exception.py +37 -0
  22. osbot_utils/decorators/methods/capture_status.py +20 -0
  23. osbot_utils/decorators/methods/catch.py +13 -0
  24. osbot_utils/decorators/methods/context.py +11 -0
  25. osbot_utils/decorators/methods/depreciated.py +79 -0
  26. osbot_utils/decorators/methods/function_type_check.py +62 -0
  27. osbot_utils/decorators/methods/obj_as_context.py +6 -0
  28. osbot_utils/decorators/methods/remove_return_value.py +22 -0
  29. osbot_utils/decorators/methods/required_fields.py +19 -0
  30. osbot_utils/fluent/Fluent_Dict.py +19 -0
  31. osbot_utils/fluent/Fluent_List.py +44 -0
  32. osbot_utils/fluent/__init__.py +1 -0
  33. osbot_utils/graphs/__init__.py +0 -0
  34. osbot_utils/graphs/mermaid/Mermaid.py +75 -0
  35. osbot_utils/graphs/mermaid/Mermaid__Edge.py +49 -0
  36. osbot_utils/graphs/mermaid/Mermaid__Graph.py +93 -0
  37. osbot_utils/graphs/mermaid/Mermaid__Node.py +69 -0
  38. osbot_utils/graphs/mermaid/Mermaid__Renderer.py +54 -0
  39. osbot_utils/graphs/mermaid/configs/Mermaid__Edge__Config.py +7 -0
  40. osbot_utils/graphs/mermaid/configs/Mermaid__Node__Config.py +9 -0
  41. osbot_utils/graphs/mermaid/configs/Mermaid__Render__Config.py +7 -0
  42. osbot_utils/graphs/mermaid/examples/Mermaid_Examples__FlowChart.py +98 -0
  43. osbot_utils/graphs/mermaid/models/Mermaid__Diagram_Direction.py +9 -0
  44. osbot_utils/graphs/mermaid/models/Mermaid__Diagram__Type.py +17 -0
  45. osbot_utils/graphs/mermaid/models/Mermaid__Node__Shape.py +30 -0
  46. osbot_utils/graphs/mgraph/MGraph.py +53 -0
  47. osbot_utils/graphs/mgraph/MGraph__Config.py +7 -0
  48. osbot_utils/graphs/mgraph/MGraph__Data.py +139 -0
  49. osbot_utils/graphs/mgraph/MGraph__Edge.py +27 -0
  50. osbot_utils/graphs/mgraph/MGraph__Node.py +33 -0
  51. osbot_utils/graphs/mgraph/MGraph__Random_Graphs.py +27 -0
  52. osbot_utils/graphs/mgraph/MGraph__Serializer.py +43 -0
  53. osbot_utils/graphs/mgraph/MGraphs.py +17 -0
  54. osbot_utils/graphs/mgraph/__init__.py +0 -0
  55. osbot_utils/helpers/CPrint.py +98 -0
  56. osbot_utils/helpers/Dict_To_Attr.py +7 -0
  57. osbot_utils/helpers/Local_Cache.py +111 -0
  58. osbot_utils/helpers/Local_Caches.py +54 -0
  59. osbot_utils/helpers/Print_Table.py +369 -0
  60. osbot_utils/helpers/Python_Audit.py +45 -0
  61. osbot_utils/helpers/Random_Seed.py +27 -0
  62. osbot_utils/helpers/SCP.py +58 -0
  63. osbot_utils/helpers/SSH.py +151 -0
  64. osbot_utils/helpers/Type_Registry.py +16 -0
  65. osbot_utils/helpers/__init__.py +0 -0
  66. osbot_utils/helpers/ast/Ast.py +35 -0
  67. osbot_utils/helpers/ast/Ast_Base.py +124 -0
  68. osbot_utils/helpers/ast/Ast_Data.py +28 -0
  69. osbot_utils/helpers/ast/Ast_Load.py +62 -0
  70. osbot_utils/helpers/ast/Ast_Merge.py +26 -0
  71. osbot_utils/helpers/ast/Ast_Node.py +117 -0
  72. osbot_utils/helpers/ast/Ast_Visit.py +85 -0
  73. osbot_utils/helpers/ast/Call_Tree.py +38 -0
  74. osbot_utils/helpers/ast/__init__.py +145 -0
  75. osbot_utils/helpers/ast/nodes/Ast_Add.py +6 -0
  76. osbot_utils/helpers/ast/nodes/Ast_Alias.py +6 -0
  77. osbot_utils/helpers/ast/nodes/Ast_And.py +6 -0
  78. osbot_utils/helpers/ast/nodes/Ast_Argument.py +7 -0
  79. osbot_utils/helpers/ast/nodes/Ast_Arguments.py +10 -0
  80. osbot_utils/helpers/ast/nodes/Ast_Assert.py +7 -0
  81. osbot_utils/helpers/ast/nodes/Ast_Assign.py +8 -0
  82. osbot_utils/helpers/ast/nodes/Ast_Attribute.py +9 -0
  83. osbot_utils/helpers/ast/nodes/Ast_Aug_Assign.py +9 -0
  84. osbot_utils/helpers/ast/nodes/Ast_Bin_Op.py +8 -0
  85. osbot_utils/helpers/ast/nodes/Ast_Bool_Op.py +7 -0
  86. osbot_utils/helpers/ast/nodes/Ast_Break.py +7 -0
  87. osbot_utils/helpers/ast/nodes/Ast_Call.py +17 -0
  88. osbot_utils/helpers/ast/nodes/Ast_Class_Def.py +9 -0
  89. osbot_utils/helpers/ast/nodes/Ast_Compare.py +9 -0
  90. osbot_utils/helpers/ast/nodes/Ast_Comprehension.py +10 -0
  91. osbot_utils/helpers/ast/nodes/Ast_Constant.py +6 -0
  92. osbot_utils/helpers/ast/nodes/Ast_Continue.py +7 -0
  93. osbot_utils/helpers/ast/nodes/Ast_Dict.py +8 -0
  94. osbot_utils/helpers/ast/nodes/Ast_Eq.py +6 -0
  95. osbot_utils/helpers/ast/nodes/Ast_Except_Handler.py +9 -0
  96. osbot_utils/helpers/ast/nodes/Ast_Expr.py +7 -0
  97. osbot_utils/helpers/ast/nodes/Ast_For.py +10 -0
  98. osbot_utils/helpers/ast/nodes/Ast_Function_Def.py +17 -0
  99. osbot_utils/helpers/ast/nodes/Ast_Generator_Exp.py +8 -0
  100. osbot_utils/helpers/ast/nodes/Ast_Gt.py +7 -0
  101. osbot_utils/helpers/ast/nodes/Ast_GtE.py +7 -0
  102. osbot_utils/helpers/ast/nodes/Ast_If.py +9 -0
  103. osbot_utils/helpers/ast/nodes/Ast_If_Exp.py +9 -0
  104. osbot_utils/helpers/ast/nodes/Ast_Import.py +7 -0
  105. osbot_utils/helpers/ast/nodes/Ast_Import_From.py +7 -0
  106. osbot_utils/helpers/ast/nodes/Ast_In.py +6 -0
  107. osbot_utils/helpers/ast/nodes/Ast_Is.py +6 -0
  108. osbot_utils/helpers/ast/nodes/Ast_Is_Not.py +7 -0
  109. osbot_utils/helpers/ast/nodes/Ast_Keyword.py +8 -0
  110. osbot_utils/helpers/ast/nodes/Ast_Lambda.py +8 -0
  111. osbot_utils/helpers/ast/nodes/Ast_List.py +8 -0
  112. osbot_utils/helpers/ast/nodes/Ast_List_Comp.py +8 -0
  113. osbot_utils/helpers/ast/nodes/Ast_Load.py +6 -0
  114. osbot_utils/helpers/ast/nodes/Ast_Lt.py +7 -0
  115. osbot_utils/helpers/ast/nodes/Ast_LtE.py +7 -0
  116. osbot_utils/helpers/ast/nodes/Ast_Mod.py +6 -0
  117. osbot_utils/helpers/ast/nodes/Ast_Module.py +20 -0
  118. osbot_utils/helpers/ast/nodes/Ast_Mult.py +6 -0
  119. osbot_utils/helpers/ast/nodes/Ast_Name.py +6 -0
  120. osbot_utils/helpers/ast/nodes/Ast_Not.py +7 -0
  121. osbot_utils/helpers/ast/nodes/Ast_Not_Eq.py +7 -0
  122. osbot_utils/helpers/ast/nodes/Ast_Not_In.py +6 -0
  123. osbot_utils/helpers/ast/nodes/Ast_Or.py +7 -0
  124. osbot_utils/helpers/ast/nodes/Ast_Pass.py +7 -0
  125. osbot_utils/helpers/ast/nodes/Ast_Pow.py +7 -0
  126. osbot_utils/helpers/ast/nodes/Ast_Raise.py +8 -0
  127. osbot_utils/helpers/ast/nodes/Ast_Return.py +7 -0
  128. osbot_utils/helpers/ast/nodes/Ast_Set.py +7 -0
  129. osbot_utils/helpers/ast/nodes/Ast_Slice.py +8 -0
  130. osbot_utils/helpers/ast/nodes/Ast_Starred.py +8 -0
  131. osbot_utils/helpers/ast/nodes/Ast_Store.py +7 -0
  132. osbot_utils/helpers/ast/nodes/Ast_Sub.py +7 -0
  133. osbot_utils/helpers/ast/nodes/Ast_Subscript.py +8 -0
  134. osbot_utils/helpers/ast/nodes/Ast_Try.py +9 -0
  135. osbot_utils/helpers/ast/nodes/Ast_Tuple.py +9 -0
  136. osbot_utils/helpers/ast/nodes/Ast_Unary_Op.py +7 -0
  137. osbot_utils/helpers/ast/nodes/Ast_While.py +8 -0
  138. osbot_utils/helpers/ast/nodes/Ast_With.py +7 -0
  139. osbot_utils/helpers/ast/nodes/Ast_With_Item.py +7 -0
  140. osbot_utils/helpers/ast/nodes/Ast_Yield.py +7 -0
  141. osbot_utils/helpers/ast/nodes/__init__.py +0 -0
  142. osbot_utils/helpers/html/Dict_To_Css.py +20 -0
  143. osbot_utils/helpers/html/Dict_To_Html.py +59 -0
  144. osbot_utils/helpers/html/Dict_To_Tags.py +88 -0
  145. osbot_utils/helpers/html/Html_To_Dict.py +75 -0
  146. osbot_utils/helpers/html/Html_To_Tag.py +20 -0
  147. osbot_utils/helpers/html/Tag__Base.py +91 -0
  148. osbot_utils/helpers/html/Tag__Body.py +5 -0
  149. osbot_utils/helpers/html/Tag__Div.py +5 -0
  150. osbot_utils/helpers/html/Tag__H.py +9 -0
  151. osbot_utils/helpers/html/Tag__HR.py +5 -0
  152. osbot_utils/helpers/html/Tag__Head.py +32 -0
  153. osbot_utils/helpers/html/Tag__Html.py +42 -0
  154. osbot_utils/helpers/html/Tag__Link.py +17 -0
  155. osbot_utils/helpers/html/Tag__Style.py +25 -0
  156. osbot_utils/helpers/html/__init__.py +0 -0
  157. osbot_utils/helpers/pubsub/Event__Queue.py +95 -0
  158. osbot_utils/helpers/pubsub/PubSub__Client.py +53 -0
  159. osbot_utils/helpers/pubsub/PubSub__Room.py +13 -0
  160. osbot_utils/helpers/pubsub/PubSub__Server.py +94 -0
  161. osbot_utils/helpers/pubsub/PubSub__Sqlite.py +24 -0
  162. osbot_utils/helpers/pubsub/__init__.py +0 -0
  163. osbot_utils/helpers/pubsub/schemas/Schema__Event.py +15 -0
  164. osbot_utils/helpers/pubsub/schemas/Schema__Event__Connect.py +7 -0
  165. osbot_utils/helpers/pubsub/schemas/Schema__Event__Disconnect.py +7 -0
  166. osbot_utils/helpers/pubsub/schemas/Schema__Event__Join_Room.py +8 -0
  167. osbot_utils/helpers/pubsub/schemas/Schema__Event__Leave_Room.py +8 -0
  168. osbot_utils/helpers/pubsub/schemas/Schema__Event__Message.py +7 -0
  169. osbot_utils/helpers/pubsub/schemas/Schema__PubSub__Client.py +8 -0
  170. osbot_utils/helpers/pubsub/schemas/__init__.py +0 -0
  171. osbot_utils/helpers/sqlite/Capture_Sqlite_Error.py +51 -0
  172. osbot_utils/helpers/sqlite/Sqlite__Cursor.py +87 -0
  173. osbot_utils/helpers/sqlite/Sqlite__Database.py +137 -0
  174. osbot_utils/helpers/sqlite/Sqlite__Field.py +70 -0
  175. osbot_utils/helpers/sqlite/Sqlite__Globals.py +5 -0
  176. osbot_utils/helpers/sqlite/Sqlite__Table.py +293 -0
  177. osbot_utils/helpers/sqlite/Sqlite__Table__Create.py +96 -0
  178. osbot_utils/helpers/sqlite/Temp_Sqlite__Database__Disk.py +17 -0
  179. osbot_utils/helpers/sqlite/Temp_Sqlite__Table.py +23 -0
  180. osbot_utils/helpers/sqlite/__init__.py +0 -0
  181. osbot_utils/helpers/sqlite/domains/Sqlite__Cache__Requests.py +214 -0
  182. osbot_utils/helpers/sqlite/domains/Sqlite__Cache__Requests__Patch.py +63 -0
  183. osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +23 -0
  184. osbot_utils/helpers/sqlite/domains/Sqlite__DB__Graph.py +47 -0
  185. osbot_utils/helpers/sqlite/domains/Sqlite__DB__Json.py +83 -0
  186. osbot_utils/helpers/sqlite/domains/Sqlite__DB__Local.py +20 -0
  187. osbot_utils/helpers/sqlite/domains/Sqlite__DB__Requests.py +39 -0
  188. osbot_utils/helpers/sqlite/domains/__init__.py +0 -0
  189. osbot_utils/helpers/sqlite/domains/schemas/Schema__Table__Requests.py +12 -0
  190. osbot_utils/helpers/sqlite/domains/schemas/__init__.py +0 -0
  191. osbot_utils/helpers/sqlite/models/Sqlite__Field__Type.py +37 -0
  192. osbot_utils/helpers/sqlite/models/__init__.py +0 -0
  193. osbot_utils/helpers/sqlite/sample_data/Sqlite__Sample_Data__Chinook.py +116 -0
  194. osbot_utils/helpers/sqlite/sample_data/__init__.py +0 -0
  195. osbot_utils/helpers/sqlite/sql_builder/SQL_Builder.py +159 -0
  196. osbot_utils/helpers/sqlite/sql_builder/SQL_Builder__Select.py +12 -0
  197. osbot_utils/helpers/sqlite/sql_builder/__init__.py +0 -0
  198. osbot_utils/helpers/sqlite/tables/Sqlite__Table__Config.py +63 -0
  199. osbot_utils/helpers/sqlite/tables/Sqlite__Table__Edges.py +46 -0
  200. osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +45 -0
  201. osbot_utils/helpers/sqlite/tables/Sqlite__Table__Nodes.py +52 -0
  202. osbot_utils/helpers/sqlite/tables/__init__.py +0 -0
  203. osbot_utils/helpers/trace/Trace_Call.py +120 -0
  204. osbot_utils/helpers/trace/Trace_Call__Config.py +94 -0
  205. osbot_utils/helpers/trace/Trace_Call__Graph.py +26 -0
  206. osbot_utils/helpers/trace/Trace_Call__Handler.py +215 -0
  207. osbot_utils/helpers/trace/Trace_Call__Print_Lines.py +85 -0
  208. osbot_utils/helpers/trace/Trace_Call__Print_Traces.py +170 -0
  209. osbot_utils/helpers/trace/Trace_Call__Stack.py +166 -0
  210. osbot_utils/helpers/trace/Trace_Call__Stack_Node.py +59 -0
  211. osbot_utils/helpers/trace/Trace_Call__Stats.py +71 -0
  212. osbot_utils/helpers/trace/Trace_Call__View_Model.py +75 -0
  213. osbot_utils/helpers/trace/Trace_Files.py +33 -0
  214. osbot_utils/helpers/trace/__init__.py +0 -0
  215. osbot_utils/testing/Catch.py +54 -0
  216. osbot_utils/testing/Duration.py +69 -0
  217. osbot_utils/testing/Hook_Method.py +118 -0
  218. osbot_utils/testing/Log_To_Queue.py +46 -0
  219. osbot_utils/testing/Log_To_String.py +37 -0
  220. osbot_utils/testing/Logging.py +81 -0
  221. osbot_utils/testing/Patch_Print.py +52 -0
  222. osbot_utils/testing/Profiler.py +89 -0
  223. osbot_utils/testing/Stderr.py +19 -0
  224. osbot_utils/testing/Stdout.py +19 -0
  225. osbot_utils/testing/Temp_File.py +46 -0
  226. osbot_utils/testing/Temp_Folder.py +114 -0
  227. osbot_utils/testing/Temp_Sys_Path.py +13 -0
  228. osbot_utils/testing/Temp_Web_Server.py +83 -0
  229. osbot_utils/testing/Temp_Zip.py +45 -0
  230. osbot_utils/testing/Temp_Zip_In_Memory.py +90 -0
  231. osbot_utils/testing/Unit_Test.py +34 -0
  232. osbot_utils/testing/Unzip_File.py +30 -0
  233. osbot_utils/testing/__init__.py +0 -0
  234. osbot_utils/utils/Assert.py +52 -0
  235. osbot_utils/utils/Call_Stack.py +187 -0
  236. osbot_utils/utils/Csv.py +32 -0
  237. osbot_utils/utils/Dev.py +47 -0
  238. osbot_utils/utils/Exceptions.py +7 -0
  239. osbot_utils/utils/Files.py +528 -0
  240. osbot_utils/utils/Functions.py +113 -0
  241. osbot_utils/utils/Http.py +136 -0
  242. osbot_utils/utils/Int.py +6 -0
  243. osbot_utils/utils/Json.py +171 -0
  244. osbot_utils/utils/Json_Cache.py +59 -0
  245. osbot_utils/utils/Lists.py +198 -0
  246. osbot_utils/utils/Misc.py +496 -0
  247. osbot_utils/utils/Objects.py +341 -0
  248. osbot_utils/utils/Png.py +29 -0
  249. osbot_utils/utils/Process.py +73 -0
  250. osbot_utils/utils/Python_Logger.py +301 -0
  251. osbot_utils/utils/Status.py +79 -0
  252. osbot_utils/utils/Str.py +63 -0
  253. osbot_utils/utils/Version.py +16 -0
  254. osbot_utils/utils/Zip.py +97 -0
  255. osbot_utils/utils/__init__.py +16 -0
  256. osbot_utils/version +1 -0
  257. osbot_utils-1.7.7.dist-info/LICENSE +201 -0
  258. osbot_utils-1.7.7.dist-info/METADATA +46 -0
  259. osbot_utils-1.7.7.dist-info/RECORD +260 -0
  260. osbot_utils-1.7.7.dist-info/WHEEL +4 -0
@@ -0,0 +1,136 @@
1
+ import json
2
+ import socket
3
+ import ssl
4
+ from time import sleep
5
+ from urllib.request import Request, urlopen
6
+
7
+ from osbot_utils.utils.Files import save_bytes_as_file, file_size, file_bytes, file_open_bytes, file_create
8
+ from osbot_utils.utils.Python_Logger import Python_Logger
9
+
10
+ URL_CHECK_HOST_ONLINE = 'https://www.google.com'
11
+
12
+ def current_host_offline(url_to_use=URL_CHECK_HOST_ONLINE):
13
+ return current_host_online(url_to_use=url_to_use) is False
14
+
15
+ def current_host_online(url_to_use=URL_CHECK_HOST_ONLINE):
16
+ try:
17
+ http_request(url_to_use, method='HEAD')
18
+ return True
19
+ except:
20
+ return False
21
+
22
+ def dns_ip_address(host):
23
+ return socket.gethostbyname(host)
24
+
25
+ def is_port_open(host, port, timeout=0.5):
26
+ return port_is_open(host=host, port=port, timeout=timeout)
27
+
28
+ def port_is_open(port : int , host='0.0.0.0', timeout=1.0):
29
+ try:
30
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
31
+ sock.settimeout(timeout)
32
+ result = sock.connect_ex((host, port))
33
+ return result == 0
34
+ except:
35
+ return False
36
+
37
+
38
+ def http_request(url, data=None, headers=None, method='GET', encoding ='utf-8', return_response_object=False):
39
+ ssl_request = url.startswith('https://')
40
+ headers = headers or {}
41
+ if data:
42
+ print()
43
+ if type(data) is not str: # if the data object is not a string
44
+ if headers.get('Content-Type') == "application/json": # and a json payload is expected
45
+ data = json.dumps(data) # convert it to json
46
+ if type(data) is str: # only convert to bytes if current data is a string
47
+ data = data.encode()
48
+ request = Request(url, data=data, headers=headers)
49
+ request.get_method = lambda: method
50
+
51
+ if ssl_request:
52
+ gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
53
+ response = urlopen(request, context=gcontext)
54
+ else:
55
+ response = urlopen(request)
56
+
57
+ if return_response_object:
58
+ return response
59
+ else:
60
+ result = response.read()
61
+ if encoding:
62
+ return result.decode(encoding)
63
+ return result
64
+
65
+ def port_is_not_open(port, host='0.0.0.0', timeout=1.0):
66
+ return port_is_open(port, host,timeout) is False
67
+
68
+ def wait_for_http(url, max_attempts=20, wait_for=0.1):
69
+ for i in range(max_attempts):
70
+ try:
71
+ if GET(url):
72
+ return True
73
+ except:
74
+ pass
75
+ sleep(wait_for)
76
+ return False
77
+
78
+ def wait_for_ssh(host, max_attempts=120, wait_for=0.5):
79
+ return wait_for_port(host=host, port=22, max_attempts=max_attempts, wait_for=wait_for)
80
+
81
+ def wait_for_port(host, port, max_attempts=20, wait_for=0.1):
82
+ for i in range(max_attempts):
83
+ if is_port_open(host=host,port=port,timeout=wait_for):
84
+ return True
85
+ sleep(wait_for)
86
+ return False
87
+
88
+ def wait_for_port_closed(host, port, max_attempts=20, wait_for=0.1):
89
+ for i in range(max_attempts):
90
+ if is_port_open(host=host,port=port,timeout=wait_for) is False:
91
+ return True
92
+ sleep(wait_for)
93
+ return False
94
+
95
+ def DELETE(url, data=None, headers=None):
96
+ return http_request(url, data, headers, 'DELETE')
97
+
98
+ def DELETE_json(*args, **kwargs):
99
+ return json.loads(DELETE(*args, **kwargs))
100
+
101
+ def GET(url,headers = None, encoding='utf-8'):
102
+ return http_request(url, headers=headers, method='GET', encoding=encoding)
103
+
104
+ def GET_to_file(url,path=None, headers = None, extension=None):
105
+ contents = GET(url, headers)
106
+ return file_create(path=path, contents=contents,extension=extension)
107
+
108
+ def GET_bytes(url, headers=None):
109
+ return GET(url, headers=headers, encoding=None)
110
+
111
+ def GET_bytes_to_file(url,path=None, headers = None):
112
+ file_bytes = GET_bytes(url, headers)
113
+ return save_bytes_as_file(file_bytes, path)
114
+
115
+ def GET_json(*args, **kwargs):
116
+ return json.loads(GET(*args, **kwargs))
117
+
118
+ def OPTIONS(url,headers = None):
119
+ response = http_request(url, headers=headers, method='OPTIONS', return_response_object=True)
120
+ response_headers = {}
121
+ for response_header in response.getheaders():
122
+ (name,value) = response_header
123
+ response_headers[name] = value
124
+ return response_headers
125
+
126
+ def POST(url, data='', headers=None):
127
+ return http_request(url, data, headers, 'POST')
128
+
129
+ def POST_json(*args, **kwargs):
130
+ return json.loads(POST(*args, **kwargs))
131
+
132
+ def PUT(url, data='', headers=None):
133
+ return http_request(url, data, headers, 'PUT')
134
+
135
+ def PUT_json(*args, **kwargs):
136
+ return json.loads(PUT(*args, **kwargs))
@@ -0,0 +1,6 @@
1
+ @staticmethod
2
+ def int_is_even(number):
3
+ return number % 2 == 0
4
+
5
+ def int_is_odd(number):
6
+ return int_is_even(number) is False
@@ -0,0 +1,171 @@
1
+ import json
2
+ import gzip
3
+ import logging
4
+ import os
5
+
6
+ from osbot_utils.utils.Misc import str_lines, str_md5, str_sha256
7
+ from osbot_utils.utils.Status import log_exception
8
+
9
+ logger_json = logging.getLogger() # todo: start using this API for capturing error messages from methods bellow
10
+
11
+ from osbot_utils.utils.Files import file_create_gz, file_create, load_file_gz, file_contents, file_lines, file_lines_gz
12
+
13
+
14
+ def json_dumps(python_object, indent=4, pretty=True, sort_keys=False, default=str, raise_exception=False):
15
+ if python_object:
16
+ try:
17
+ if pretty:
18
+ return json.dumps(python_object, indent=indent, sort_keys=sort_keys, default=default)
19
+ return json.dumps(python_object, default=default)
20
+ except Exception as error:
21
+ error_message = f'Error in load_json: {error}'
22
+ log_exception(message=error_message, error=error)
23
+ if raise_exception:
24
+ raise error
25
+
26
+
27
+ def json_dumps_to_bytes(*args, **kwargs):
28
+ return json_dumps(*args, **kwargs).encode()
29
+
30
+ def json_lines_file_load(target_path):
31
+ raw_json = '[' # start the json array
32
+ lines = file_lines(target_path) # get all lines from the file provided in target_path
33
+ raw_json += ','.join(lines) # add lines to raw_json split by json array separator
34
+ raw_json += ']' # close the json array
35
+ return json_parse(raw_json) # convert json data into a python object
36
+
37
+ def json_lines_file_load_gz(target_path):
38
+ raw_json = '[' # start the json array
39
+ lines = file_lines_gz(target_path) # get all lines from the file provided in target_path
40
+ raw_json += ','.join(lines) # add lines to raw_json split by json array separator
41
+ raw_json += ']' # close the json array
42
+ return json_parse(raw_json) # convert json data into a python object
43
+
44
+
45
+ def json_sha_256(target):
46
+ return str_sha256(json_dumps(target))
47
+
48
+
49
+
50
+ class Json:
51
+
52
+ @staticmethod
53
+ def load_file(path):
54
+ """
55
+ Loads json data from file
56
+ Note: will not throw errors and will return {} as default
57
+ errors are logged to Json.log
58
+ """
59
+ json_data = file_contents(path)
60
+ return json_loads(json_data)
61
+
62
+ @staticmethod
63
+ def load_file_and_delete(path):
64
+ data = json_load_file(path)
65
+ if data:
66
+ os.remove(path)
67
+ return data
68
+
69
+ @staticmethod
70
+ def load_file_gz(path):
71
+ data = load_file_gz(path)
72
+ return json_loads(data)
73
+
74
+ @staticmethod
75
+ def load_file_gz_and_delete(path):
76
+ data = json_load_file_gz(path)
77
+ if data:
78
+ os.remove(path)
79
+ return data
80
+
81
+ @staticmethod
82
+ def loads(json_data, raise_exception=False):
83
+ """
84
+ Loads json data from string
85
+ Note: will not throw errors and will return {} as default
86
+ errors are logged to Json.log
87
+ """
88
+ if json_data:
89
+ try:
90
+ return json.loads(json_data)
91
+ except Exception as error:
92
+ log_exception(message='Error in load_json', error=error)
93
+ if raise_exception:
94
+ raise error
95
+
96
+ return {}
97
+
98
+ @staticmethod
99
+ def loads_json_lines(json_lines):
100
+ json_data = '[' + ','.join(str_lines(json_lines.strip())) + ']'
101
+ return json_loads(json_data)
102
+
103
+ @staticmethod
104
+ def md5(data):
105
+ return str_md5(json_dump(data))
106
+
107
+ @staticmethod
108
+ def round_trip(data):
109
+ return json_loads(json_dumps(data))
110
+
111
+ @staticmethod
112
+ def save_file(python_object, path=None, pretty=False, sort_keys=False):
113
+ json_data = json_dumps(python_object=python_object, indent=2, pretty=pretty, sort_keys=sort_keys)
114
+ return file_create(path=path, contents=json_data)
115
+
116
+ @staticmethod
117
+ def save_file_pretty(python_object, path=None):
118
+ return json_save_file(python_object=python_object, path=path, pretty=True)
119
+
120
+ @staticmethod
121
+ def save_file_gz(python_object, path=None, pretty=False):
122
+ json_data = json_dumps(python_object,indent=2, pretty=pretty)
123
+ return file_create_gz(path=path, contents=json_data)
124
+
125
+ @staticmethod
126
+ def save_file_pretty_gz(python_object, path=None):
127
+ return json_save_file_gz(python_object=python_object, path=path, pretty=True)
128
+
129
+
130
+ @staticmethod
131
+ def json_save_tmp_file(python_object, pretty=True):
132
+ return Json.save_file(python_object=python_object, pretty=pretty, path=None)
133
+
134
+ file_create_json = Json.save_file_pretty
135
+ file_contents_json = Json.load_file
136
+
137
+ json_dump = json_dumps
138
+ json_format = json_dumps
139
+ json_file_create = Json.save_file
140
+ json_file_create_gz = Json.save_file_gz
141
+ json_file_contents = Json.load_file
142
+ json_file_contents_gz = Json.load_file_gz
143
+ json_file_load = Json.load_file
144
+ json_file_safe = Json.save_file
145
+ json_from_file = Json.load_file
146
+ json_load_file = Json.load_file
147
+ json_load_file_and_delete = Json.load_file_and_delete
148
+ json_load_file_gz = Json.load_file_gz
149
+ json_load_file_gz_and_delete = Json.load_file_gz_and_delete
150
+ json_from_string = Json.loads
151
+ json_load = Json.loads
152
+ json_loads = Json.loads
153
+ json_md5 = Json.md5
154
+ json_lines_loads = Json.loads_json_lines
155
+ json_parse = Json.loads
156
+ json_lines_parse = Json.loads_json_lines
157
+ json_to_str = json_dumps
158
+ json_round_trip = Json.round_trip
159
+ json_save = Json.save_file
160
+ json_save_file = Json.save_file
161
+ json_save_file_pretty = Json.save_file_pretty
162
+ json_save_file_gz = Json.save_file_gz
163
+ json_save_file_pretty_gz = Json.save_file_pretty_gz
164
+ json_save_tmp_file = Json.json_save_tmp_file
165
+ str_to_json = Json.loads
166
+
167
+ load_file_json = json_load_file
168
+ load_file_json_gz = json_load_file_gz
169
+
170
+ to_json_str = json_dumps
171
+ from_json_str = json_loads
@@ -0,0 +1,59 @@
1
+ from osbot_utils.utils.Files import path_combine, folder_create, file_delete, file_exists
2
+ from osbot_utils.utils.Json import json_save_file_gz, json_save_file, json_load_file_gz, json_load_file
3
+ from osbot_utils.utils.Str import str_safe
4
+
5
+ PATH_TEMP_FOLDER = '/tmp/json_cache'
6
+
7
+ class Json_Cache:
8
+
9
+ def __init__(self, cache_type=None, cache_keys=None):
10
+ self.cache_type = cache_type or '__cache'
11
+ self.cache_keys = cache_keys or [self.cache_type]
12
+ self.path_tmp_folder = PATH_TEMP_FOLDER
13
+ self.save_as_gz = True
14
+ if type(self.cache_keys) is not list and type(self.cache_keys) is not tuple:
15
+ self.cache_keys = [self.cache_keys]
16
+ #self.data = None
17
+
18
+ def __enter__(self):
19
+ return self
20
+
21
+ def __exit__(self, exc_type, exc_val, exc_tb):
22
+ pass
23
+
24
+ def data(self):
25
+ file_path = self.path_cache_file()
26
+ if self.exists():
27
+ if self.save_as_gz:
28
+ return json_load_file_gz(file_path)
29
+ else:
30
+ return json_load_file(file_path)
31
+ return None
32
+
33
+ def delete(self):
34
+ return file_delete(self.path_cache_file())
35
+
36
+ def exists(self):
37
+ return file_exists(self.path_cache_file())
38
+
39
+ def save(self, data):
40
+ file_path = self.path_cache_file()
41
+ if self.save_as_gz:
42
+ return json_save_file_gz(data, file_path)
43
+ else:
44
+ return json_save_file(data, file_path)
45
+
46
+ def path_cache_folder(self):
47
+ path_cache = path_combine(self.path_tmp_folder, self.cache_type)
48
+ folder_create(path_cache)
49
+ return path_cache
50
+
51
+ def path_cache_file(self):
52
+ tmp_file_name = ""#str_safe(str(self.cache_type))
53
+ for cache_key in self.cache_keys:
54
+ tmp_file_name += f"--{str_safe(str(cache_key))}"
55
+ tmp_file_name += ".json"
56
+ if self.save_as_gz:
57
+ tmp_file_name += ".gz"
58
+ file_path = path_combine(self.path_cache_folder(), tmp_file_name)
59
+ return file_path
@@ -0,0 +1,198 @@
1
+ import sys
2
+ from typing import List
3
+
4
+ from osbot_utils.utils.Misc import list_set
5
+
6
+ from osbot_utils.utils.Str import trim
7
+
8
+ def len_list(target):
9
+ if type(target) is list:
10
+ return len(list(target))
11
+ return 0
12
+
13
+ def list_add(array : list, value):
14
+ if value is not None:
15
+ array.append(value)
16
+ return value
17
+
18
+ def list_chunks(items:list, split: int):
19
+ if items and split and split > 0:
20
+ for i in range(0, len(items), split):
21
+ yield items[i:i + split]
22
+
23
+ def list_contains_list(array : list, values):
24
+ if array is not None:
25
+ if type(values) is list:
26
+ for item in values:
27
+ if (item in array) is False:
28
+ return False
29
+ return True
30
+ return False
31
+
32
+ def list_delete(target, item):
33
+ if item in target:
34
+ target.remove(item)
35
+ return target
36
+
37
+ def list_empty(list):
38
+ return not list_not_empty(list)
39
+
40
+ def list_filter(target_list, filter_function):
41
+ return list(filter(filter_function, target_list))
42
+
43
+ def list_filter_starts_with(target_list, prefix):
44
+ return list_filter(target_list, lambda x: x.startswith(prefix))
45
+
46
+ def list_filter_contains(target_list, value):
47
+ return list_filter(target_list, lambda x: x.find(value) > -1)
48
+
49
+ def list_find(array:list, item):
50
+ if item in array:
51
+ return array.index(item)
52
+ return -1
53
+
54
+ def list_first(list, strip=False):
55
+ if list_not_empty(list):
56
+ value = list[0]
57
+ if strip:
58
+ value = value.strip()
59
+ return value
60
+
61
+ def list_in_list(source : list, target: list):
62
+ return set(source).issubset(set(target))
63
+
64
+ def list_get(array, position=None, default=None):
65
+ if type(array) is list:
66
+ if type(position) is int and position >=0 :
67
+ if len(array) > position:
68
+ return array[position]
69
+ return default
70
+
71
+ def list_get_field(values, field):
72
+ if type(values) is list:
73
+ return [item.get(field) for item in values]
74
+ return []
75
+
76
+ def list_group_by(values, group_by):
77
+ results = {}
78
+ if type(values) is list:
79
+ for item in values:
80
+ value = str(item.get(group_by))
81
+ if results.get(value) is None: results[value] = []
82
+ results[value].append(item)
83
+ return results
84
+
85
+ def list_index_by(values, index_by):
86
+ from osbot_utils.fluent.Fluent_Dict import Fluent_Dict
87
+ results = {}
88
+ if values and index_by:
89
+ for item in values:
90
+ results[item.get(index_by)] = item
91
+ return Fluent_Dict(results)
92
+
93
+ def list_lower(input_list):
94
+ return [item.lower() for item in input_list]
95
+
96
+ def list_not_empty(list):
97
+ if list and type(list).__name__ == 'list' and len(list) >0:
98
+ return True
99
+ return False
100
+
101
+ def list_order_by(target: List[dict], key: str, reverse: bool=False) -> List[dict]:
102
+ if target and key:
103
+ return sorted(target, key=lambda x: x[key], reverse=reverse)
104
+ return []
105
+
106
+ def list_pop(array:list, position=None, default=None):
107
+ if array:
108
+ if len(array) >0:
109
+ if type(position) is int:
110
+ if len(array) > position:
111
+ return array.pop(position)
112
+ else:
113
+ return array.pop()
114
+ return default
115
+
116
+ def list_pop_and_trim(array, position=None):
117
+ value = array_pop(array,position)
118
+ if type(value) is str:
119
+ return trim(value)
120
+ return value
121
+
122
+ def list_remove(array, item):
123
+ if type(array) is list:
124
+ if type(item) is list:
125
+ result = []
126
+ for element in array:
127
+ if element not in item:
128
+ result.append(element)
129
+ return result
130
+
131
+ return [element for element in array if element != item]
132
+ return array
133
+
134
+ def list_remove_list(source: list, target: list):
135
+ if type(source) is list and type(target) is list:
136
+ for item in target:
137
+ if item in source:
138
+ source.remove(item)
139
+ return source
140
+
141
+ def list_remove_empty(array):
142
+ if type(array) is list:
143
+ return [element for element in array if element]
144
+ return array
145
+
146
+ def list_set_dict(target):
147
+ if hasattr(target, '__dict__'):
148
+ return sorted(list(set(target.__dict__)))
149
+ return []
150
+
151
+ def list_sorted(target_list, key, descending=False):
152
+ return list(sorted(target_list, key= lambda x:x.get(key,None) ,reverse=descending))
153
+
154
+ def list_stats(target):
155
+ stats = {}
156
+ if type(target) is list:
157
+ for item in target:
158
+ if stats.get(item) is None:
159
+ stats[item] = 0
160
+ stats[item] += 1
161
+ return stats
162
+
163
+ def list_to_tuple(target: list):
164
+ if type(target) is list:
165
+ return tuple(target)
166
+
167
+ def list_zip(*args):
168
+ if args:
169
+ return list(zip(*args))
170
+
171
+ def sys_path_python(python_folder='lib/python'):
172
+ return list_contains(sys.path, python_folder)
173
+
174
+ def tuple_to_list(target:tuple):
175
+ if type(target) is tuple:
176
+ return list(target)
177
+
178
+ def tuple_replace_position(target:tuple, position,value):
179
+ tuple_as_list = tuple_to_list(target)
180
+ if len(tuple_as_list) > position:
181
+ tuple_as_list[position] = value
182
+ list_as_tuple = list_to_tuple(tuple_as_list)
183
+ return list_as_tuple
184
+
185
+ def unique(target):
186
+ return list_set(target)
187
+
188
+ array_find = list_find
189
+ array_get = list_get
190
+ array_pop = list_pop
191
+ array_pop_and_trim = list_pop_and_trim
192
+ array_add = list_add
193
+
194
+ list_contains = list_filter_contains
195
+ list_del = list_delete
196
+ list_sort_by = list_sorted
197
+
198
+ chunks = list_chunks