sunholo 0.73.2__tar.gz → 0.73.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. {sunholo-0.73.2 → sunholo-0.73.3}/PKG-INFO +2 -2
  2. {sunholo-0.73.2 → sunholo-0.73.3}/setup.py +1 -1
  3. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/chat_vac.py +99 -7
  4. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/PKG-INFO +2 -2
  5. {sunholo-0.73.2 → sunholo-0.73.3}/LICENSE.txt +0 -0
  6. {sunholo-0.73.2 → sunholo-0.73.3}/MANIFEST.in +0 -0
  7. {sunholo-0.73.2 → sunholo-0.73.3}/README.md +0 -0
  8. {sunholo-0.73.2 → sunholo-0.73.3}/setup.cfg +0 -0
  9. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/__init__.py +0 -0
  10. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/__init__.py +0 -0
  11. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/chat_history.py +0 -0
  12. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/dispatch_to_qa.py +0 -0
  13. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/fastapi/__init__.py +0 -0
  14. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/fastapi/base.py +0 -0
  15. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/fastapi/qna_routes.py +0 -0
  16. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/flask/__init__.py +0 -0
  17. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/flask/base.py +0 -0
  18. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/flask/qna_routes.py +0 -0
  19. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/flask/vac_routes.py +0 -0
  20. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/langserve.py +0 -0
  21. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/pubsub.py +0 -0
  22. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/route.py +0 -0
  23. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/special_commands.py +0 -0
  24. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/agents/swagger.py +0 -0
  25. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/archive/__init__.py +0 -0
  26. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/archive/archive.py +0 -0
  27. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/auth/__init__.py +0 -0
  28. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/auth/run.py +0 -0
  29. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/bots/__init__.py +0 -0
  30. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/bots/discord.py +0 -0
  31. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/bots/github_webhook.py +0 -0
  32. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/bots/webapp.py +0 -0
  33. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/__init__.py +0 -0
  34. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/data_to_embed_pubsub.py +0 -0
  35. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/doc_handling.py +0 -0
  36. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/images.py +0 -0
  37. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/loaders.py +0 -0
  38. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/message_data.py +0 -0
  39. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/pdfs.py +0 -0
  40. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/publish.py +0 -0
  41. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/chunker/splitter.py +0 -0
  42. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/__init__.py +0 -0
  43. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/cli.py +0 -0
  44. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/cli_init.py +0 -0
  45. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/configs.py +0 -0
  46. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/deploy.py +0 -0
  47. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/embedder.py +0 -0
  48. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/merge_texts.py +0 -0
  49. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/run_proxy.py +0 -0
  50. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/sun_rich.py +0 -0
  51. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/cli/swagger.py +0 -0
  52. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/components/__init__.py +0 -0
  53. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/components/llm.py +0 -0
  54. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/components/retriever.py +0 -0
  55. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/components/vectorstore.py +0 -0
  56. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/__init__.py +0 -0
  57. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/alloydb.py +0 -0
  58. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/alloydb_client.py +0 -0
  59. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/database.py +0 -0
  60. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/lancedb.py +0 -0
  61. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/create_function.sql +0 -0
  62. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  63. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/create_table.sql +0 -0
  64. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  65. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/return_sources.sql +0 -0
  66. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/sql/sb/setup.sql +0 -0
  67. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/static_dbs.py +0 -0
  68. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/database/uuid.py +0 -0
  69. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/discovery_engine/__init__.py +0 -0
  70. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/discovery_engine/chunker_handler.py +0 -0
  71. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/discovery_engine/create_new.py +0 -0
  72. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  73. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/embedder/__init__.py +0 -0
  74. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/embedder/embed_chunk.py +0 -0
  75. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/gcs/__init__.py +0 -0
  76. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/gcs/add_file.py +0 -0
  77. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/gcs/download_url.py +0 -0
  78. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/gcs/metadata.py +0 -0
  79. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/invoke/__init__.py +0 -0
  80. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/invoke/invoke_vac_utils.py +0 -0
  81. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/langfuse/__init__.py +0 -0
  82. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/langfuse/callback.py +0 -0
  83. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/langfuse/prompts.py +0 -0
  84. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/llamaindex/__init__.py +0 -0
  85. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/llamaindex/generate.py +0 -0
  86. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/llamaindex/get_files.py +0 -0
  87. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/llamaindex/import_files.py +0 -0
  88. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/logging.py +0 -0
  89. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/lookup/__init__.py +0 -0
  90. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/lookup/model_lookup.yaml +0 -0
  91. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/patches/__init__.py +0 -0
  92. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/patches/langchain/__init__.py +0 -0
  93. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/patches/langchain/lancedb.py +0 -0
  94. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/patches/langchain/vertexai.py +0 -0
  95. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/pubsub/__init__.py +0 -0
  96. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/pubsub/process_pubsub.py +0 -0
  97. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/pubsub/pubsub_manager.py +0 -0
  98. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/qna/__init__.py +0 -0
  99. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/qna/parsers.py +0 -0
  100. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/qna/retry.py +0 -0
  101. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/streaming/__init__.py +0 -0
  102. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/streaming/content_buffer.py +0 -0
  103. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/streaming/langserve.py +0 -0
  104. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/streaming/stream_lookup.py +0 -0
  105. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/streaming/streaming.py +0 -0
  106. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/summarise/__init__.py +0 -0
  107. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/summarise/summarise.py +0 -0
  108. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/tools/__init__.py +0 -0
  109. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/tools/web_browser.py +0 -0
  110. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/__init__.py +0 -0
  111. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/api_key.py +0 -0
  112. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/big_context.py +0 -0
  113. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/config.py +0 -0
  114. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/config_class.py +0 -0
  115. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/config_schema.py +0 -0
  116. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/gcp.py +0 -0
  117. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/gcp_project.py +0 -0
  118. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/parsers.py +0 -0
  119. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/timedelta.py +0 -0
  120. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/user_ids.py +0 -0
  121. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/utils/version.py +0 -0
  122. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/vertex/__init__.py +0 -0
  123. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/vertex/extensions_class.py +0 -0
  124. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/vertex/init.py +0 -0
  125. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/vertex/memory_tools.py +0 -0
  126. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo/vertex/safety.py +0 -0
  127. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/SOURCES.txt +0 -0
  128. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/dependency_links.txt +0 -0
  129. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/entry_points.txt +0 -0
  130. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/requires.txt +0 -0
  131. {sunholo-0.73.2 → sunholo-0.73.3}/sunholo.egg-info/top_level.txt +0 -0
  132. {sunholo-0.73.2 → sunholo-0.73.3}/tests/test_chat_history.py +0 -0
  133. {sunholo-0.73.2 → sunholo-0.73.3}/tests/test_chunker.py +0 -0
  134. {sunholo-0.73.2 → sunholo-0.73.3}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.73.2
3
+ Version: 0.73.3
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.73.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.73.3.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
  # Define your base version
4
- version = '0.73.2'
4
+ version = '0.73.3'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -8,6 +8,8 @@ from ..qna.parsers import parse_output
8
8
  from ..gcs.add_file import add_file_to_gcs
9
9
  from .run_proxy import clean_proxy_list, start_proxy, stop_proxy
10
10
  from ..invoke import invoke_vac
11
+ from ..utils.big_context import has_text_extension, merge_text_files, load_gitignore_patterns, build_file_tree
12
+ import tempfile
11
13
 
12
14
  import uuid
13
15
  import os
@@ -24,6 +26,55 @@ from rich.panel import Panel
24
26
  from rich.text import Text
25
27
  from rich.table import Table
26
28
 
29
+ def read_and_add_to_user_input(user_input):
30
+ read_input = None
31
+
32
+ path = user_input.split(" ", 1)[1] if " " in user_input else None
33
+ if not path:
34
+ console.print("[bold red]Please provide a valid file or folder path.[/bold red]")
35
+ return None
36
+
37
+ if os.path.isfile(path):
38
+ if not has_text_extension(path):
39
+ console.print("[bold red]Unsupported file type. Please provide a text file or preprocess to text, or use !upload (e.g. images) or `sunholo embed`.[/bold red]")
40
+ return None
41
+
42
+ try:
43
+ with open(path, 'r', encoding='utf-8') as file:
44
+ file_content = file.read()
45
+ read_input = file_content
46
+ console.print(f"[bold yellow]File content from {path} read into user_input: [{len(read_input.split())}] words[/bold yellow]")
47
+ except FileNotFoundError:
48
+ console.print("[bold red]File not found. Please check the path and try again.[/bold red]")
49
+ return None
50
+ except IOError:
51
+ console.print("[bold red]File could not be read. Please ensure it is a readable text file.[/bold red]")
52
+ return None
53
+ elif os.path.isdir(path):
54
+ patterns = []
55
+ gitignore_path = os.path.join(path, '.gitignore')
56
+
57
+ if os.path.exists(gitignore_path):
58
+ patterns = load_gitignore_patterns(gitignore_path)
59
+
60
+ try:
61
+ with tempfile.NamedTemporaryFile(delete=False, mode='w+', encoding='utf-8') as temp_file:
62
+ temp_file_path = temp_file.name
63
+ file_tree = merge_text_files(path, temp_file_path, patterns)
64
+ console.print(f"[bold yellow]Contents of the folder '{path}' have been merged add added to input.[/bold yellow]")
65
+ console.print("\n".join(file_tree))
66
+ temp_file.seek(0)
67
+ read_input = temp_file.read()
68
+ console.print(f"[bold yellow]Total words: [{len(read_input.split())}] - watch out for high token costs! Use !clear_read to reset[/bold yellow]")
69
+ os.remove(temp_file_path) # Clean up the temporary file
70
+ except Exception as e:
71
+ console.print(f"[bold red]An error occurred while reading the folder: {str(e)}[/bold red]")
72
+ return None
73
+ else:
74
+ console.print("[bold red]The provided path is neither a file nor a folder. Please check the path and try again.[/bold red]")
75
+ return None
76
+
77
+ return read_input
27
78
 
28
79
  def get_service_url(vac_name, project, region, no_config=False):
29
80
 
@@ -67,6 +118,8 @@ def stream_chat_session(service_url, service_name, stream=True):
67
118
  chat_history = []
68
119
  agent_name = ConfigManager(service_name).vacConfig("agent")
69
120
  file_reply = None
121
+ read_file = None
122
+ read_file_count = None
70
123
  while True:
71
124
  session_id = str(uuid.uuid4())
72
125
  user_input = Prompt.ask("[bold cyan]You[/bold cyan]")
@@ -81,9 +134,26 @@ def stream_chat_session(service_url, service_name, stream=True):
81
134
 
82
135
  if special_reply:
83
136
  console.print(f"[bold yellow]{service_name}:[/bold yellow] {special_reply}", end='\n')
84
- continue
85
-
86
- if user_input.lower().startswith("upload"):
137
+ continue
138
+
139
+ if user_input.lower().startswith("!read"):
140
+ read_file = read_and_add_to_user_input(user_input)
141
+ if read_file:
142
+ read_file_count = len(read_file.split())
143
+ continue
144
+
145
+ if user_input.lower().startswith("!ls"):
146
+ items = os.listdir(os.getcwd())
147
+ for item in items:
148
+ console.print(item)
149
+ continue
150
+
151
+ if user_input.lower().startswith("!tree"):
152
+ tree = build_file_tree(os.getcwd(), patterns=[])
153
+ console.print(tree)
154
+ continue
155
+
156
+ if user_input.lower().startswith("!upload"):
87
157
  file_path = user_input.split(" ", 1)[1] if " " in user_input else None
88
158
  if not file_path:
89
159
  console.print("[bold red]Please provide a valid file path.[/bold red]")
@@ -95,7 +165,7 @@ def stream_chat_session(service_url, service_name, stream=True):
95
165
  console.print("[bold red]Invalid file upload[/bold red]")
96
166
  continue
97
167
 
98
- console.print(f"[bold yellow]{service_name}:[/bold yellow] Uploaded {file_path} to {file_reply} - image will be sent each reply until you issue 'clear_upload' ", end='\n')
168
+ console.print(f"[bold yellow]{service_name}:[/bold yellow] Uploaded {file_path} to {file_reply} - image will be sent each reply until you issue '!clear_upload' ", end='\n')
99
169
 
100
170
  except FileNotFoundError:
101
171
  console.print("[bold red]File not found. Please check the path and try again.[/bold red]")
@@ -103,10 +173,25 @@ def stream_chat_session(service_url, service_name, stream=True):
103
173
  # file_reply stays for each message from now on
104
174
  continue
105
175
 
106
- if user_input.lower().startswith("clear_upload"):
176
+ if user_input.lower().startswith("!clear_upload"):
107
177
  console.print("[bold yellow]File upload path cleared.[/bold yellow]")
108
178
  file_path = None
179
+ continue
180
+
181
+ if user_input.lower().startswith("!clear_read"):
182
+ console.print("[bold yellow]Read in file(s) cleared.[/bold yellow]")
183
+ read_file = None
184
+ read_file_count = None
185
+ continue
109
186
 
187
+ if read_file:
188
+ user_input = f"<user added file>{read_file}</user added file>\n{user_input}"
189
+
190
+ # guardrail
191
+ if len(user_input)> 1000000:
192
+ console.print("[bold red]Over 1 million characters in user_input, aborting as probably unintentional. Use API directly instead.[/bold red]")
193
+ continue
194
+
110
195
  if not stream:
111
196
  vac_response = send_to_qa(user_input,
112
197
  vector_name=service_name,
@@ -166,8 +251,15 @@ def stream_chat_session(service_url, service_name, stream=True):
166
251
  response_started = False
167
252
  vac_response = ""
168
253
 
169
- # point or star?
170
- with console.status(f"[bold orange]Thinking...{file_reply}[/bold orange]", spinner="star") as status:
254
+
255
+ thinking = "[bold orange]Thinking...[/bold orange]"
256
+ if file_reply:
257
+ thinking = f"[bold orange]Thinking with upload {file_reply} - issue !clear_upload to remove...[/bold orange]"
258
+
259
+ if read_file:
260
+ thinking = f"{thinking} - [bold orange]additional [{read_file_count}] words added via !read_file contents - issue !clear_read to remove[/bold orange]"
261
+
262
+ with console.status(thinking, spinner="star") as status:
171
263
  for token in stream_response():
172
264
  if not response_started:
173
265
  status.stop()
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.73.2
3
+ Version: 0.73.3
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.73.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.73.3.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes