sunholo 0.72.0__py3-none-any.whl → 0.73.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,10 +2,10 @@ sunholo/__init__.py,sha256=0CdpufyRKWyZe7J7UKigL6j_qOorM-p0OjHIAuf9M38,864
2
2
  sunholo/logging.py,sha256=YfIN1oP3dOEkkYkyRBU8BGS3uJFGwUDsFCl8mIVbwvE,12225
3
3
  sunholo/agents/__init__.py,sha256=Hb4NXy2rN-83Z0-UDRwX-LXv2R29lcbSFPf8G6q4fZg,380
4
4
  sunholo/agents/chat_history.py,sha256=8iX1bgvRW6fdp6r_DQR_caPHYrZ_9QJJgPxCiSDf3q8,5380
5
- sunholo/agents/dispatch_to_qa.py,sha256=nFNdxhkr7rVYuUwVoBCBNYBI2Dke6-_z_ZApBEWb_cU,8291
6
- sunholo/agents/langserve.py,sha256=FdhQjorAY2bMn2rpuabNT6bU3uqSKWrl8DjpH3L_V7k,4375
5
+ sunholo/agents/dispatch_to_qa.py,sha256=A8skiZ-CtDvYdP0tnXL4sWM3BCDBgdjFVyrqy-h8Aa4,8374
6
+ sunholo/agents/langserve.py,sha256=eSNJ4G5eGKjmyMQLM_uTOjiS-D_W4QhCLrsC4Vsnk7E,4407
7
7
  sunholo/agents/pubsub.py,sha256=5hbbhbBGyVWRpt2sAGC5FEheYH1mCCwVUhZEB1S7vGg,1337
8
- sunholo/agents/route.py,sha256=xh8ZJuIs60AhGk-1lw-b9LLuvOIVD2sx8m41BnWMJUI,2606
8
+ sunholo/agents/route.py,sha256=YL9a99X1vwSWH8XWo3En1UryxhBFEFhjkbNN1X_YDHg,2905
9
9
  sunholo/agents/special_commands.py,sha256=ecD5jrBVXo170sdgPILi0m_m_4nRFEv6qKn5zYEvEK8,6494
10
10
  sunholo/agents/swagger.py,sha256=wK90aGOgUojZjfMcjqhhJ_ksJ6ZCsVT1Iy02oU6Q5XM,10786
11
11
  sunholo/agents/fastapi/__init__.py,sha256=S_pj4_bTUmDGoq_exaREHlOKThi0zTuGT0VZY0YfODQ,88
@@ -33,19 +33,19 @@ sunholo/chunker/pdfs.py,sha256=daCZ1xjn1YvxlifIyxskWNpLJLe-Q9D_Jq12MWx3tZo,2473
33
33
  sunholo/chunker/publish.py,sha256=tiO615A2uo_ZjzdFDzNH1PL_1kJeLMUQwLJ4w67rNIc,2932
34
34
  sunholo/chunker/splitter.py,sha256=jtGfi_ZdhVdyFhfw0e4ynEpmwIyrxQtV63OituYWy6o,6729
35
35
  sunholo/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- sunholo/cli/chat_vac.py,sha256=wvpFF2MRLVeomLcd31TK6tX61u-pL5nGEtMSE33wAK8,20705
37
- sunholo/cli/cli.py,sha256=8e00HBN6eYIUJ8cnvKteBJNn7aZPRMk4b82jwcGg9D4,3741
36
+ sunholo/cli/chat_vac.py,sha256=9NNdIt0pWLZandxtav9Eu7ru9WOBHjh1TN1oP3pqMbM,22852
37
+ sunholo/cli/cli.py,sha256=u70fcSQzQx2iPvE23SVCVYRFabmZ-XtgEd6vHcrABi0,3725
38
38
  sunholo/cli/cli_init.py,sha256=JMZ9AX2cPDZ-_mv3adiv2ToFVNyRPtjk9Biszl1kiR0,2358
39
39
  sunholo/cli/configs.py,sha256=QUM9DvKOdZmEQRM5uI3Nh887T0YDiSMr7O240zTLqws,4546
40
40
  sunholo/cli/deploy.py,sha256=zxdwUsRTRMC8U5vyRv0JiKBLFn84Ug_Tc88-_h9hJSs,1609
41
- sunholo/cli/embedder.py,sha256=w7LT1CANSoQbOz8xAP3Zt4C_hP4lzGJOf8XD2jY5jBQ,7291
41
+ sunholo/cli/embedder.py,sha256=NAiJy6DmIB3x8wY3ZZ2qHdTubjrwk603eiofWfakfCk,7311
42
42
  sunholo/cli/merge_texts.py,sha256=U9vdMwKmcPoc6iPOWX5MKSxn49dNGbNzVLw8ui5PhEU,1823
43
43
  sunholo/cli/run_proxy.py,sha256=OeR12ZfnasbJ-smBZQznmGufoDa4iNjUN9FCFo5JxSc,11520
44
44
  sunholo/cli/sun_rich.py,sha256=UpMqeJ0C8i0pkue1AHnnyyX0bFJ9zZeJ7HBR6yhuA8A,54
45
45
  sunholo/cli/swagger.py,sha256=absYKAU-7Yd2eiVNUY-g_WLl2zJfeRUNdWQ0oH8M_HM,1564
46
46
  sunholo/components/__init__.py,sha256=IDoylb74zFKo6NIS3RQqUl0PDFBGVxM1dfUmO7OJ44U,176
47
47
  sunholo/components/llm.py,sha256=T4we3tGmqUj4tPwxQr9M6AXv_BALqZV_dRSvINan-oU,10374
48
- sunholo/components/retriever.py,sha256=szXyQ-cgFOw6uokl7ajQt9AGXC0N2nLB900TVtjNRa4,6528
48
+ sunholo/components/retriever.py,sha256=BFUw_6turT3CQJZWv_uXylmH5fHdb0gKfKJrQ_j6MGY,6533
49
49
  sunholo/components/vectorstore.py,sha256=zUJ90L1S4IyxLB0JUWopeuwVjcsSqdhj1QreEfsJhsE,5548
50
50
  sunholo/database/__init__.py,sha256=Zz0Shcq-CtStf9rJGIYB_Ybzb8rY_Q9mfSj-nviM490,241
51
51
  sunholo/database/alloydb.py,sha256=d9W0pbZB0jTVIGF5OVaQ6kXHo-X3-6e9NpWNmV5e9UY,10464
@@ -67,16 +67,18 @@ sunholo/discovery_engine/discovery_engine_client.py,sha256=YYsFeaW41l8jmWCruQnYx
67
67
  sunholo/embedder/__init__.py,sha256=sI4N_CqgEVcrMDxXgxKp1FsfsB4FpjoXgPGkl4N_u4I,44
68
68
  sunholo/embedder/embed_chunk.py,sha256=d_dIzeNF630Q0Ar-u1hxos60s0tLIImJccAvuo_LTIw,6814
69
69
  sunholo/gcs/__init__.py,sha256=SZvbsMFDko40sIRHTHppA37IijvJTae54vrhooEF5-4,90
70
- sunholo/gcs/add_file.py,sha256=Nj75z1MH9fp3fvwd1BVLcHNFm0CVCR2uS4uByThos-o,6924
70
+ sunholo/gcs/add_file.py,sha256=vWRjxuHBQkrPNrr9tRSFGT0N_nVIw120mqDEHiaHwuQ,7115
71
71
  sunholo/gcs/download_url.py,sha256=Kg9EdPnc---YSUTAZEdzJeITjDtQSLMYwb4uiU9LhIQ,6440
72
72
  sunholo/gcs/metadata.py,sha256=C9sMPsHsq1ETetdQCqB3EBs3Kws8b8QHS9L7ei_v5aw,891
73
+ sunholo/invoke/__init__.py,sha256=Dxivd9cU92X4v2JAZet4f7L2RJ5l_30rt9t2NiD-iLA,55
74
+ sunholo/invoke/invoke_vac_utils.py,sha256=0JkCZDBEkRImzuB-nf70dF75t0WKtgA9G4TdaQJUB08,5240
73
75
  sunholo/langfuse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
76
  sunholo/langfuse/callback.py,sha256=CTaos8sYcrga949BG6lIZ4I62DiiQSHxwz5re9XjDWQ,1677
75
- sunholo/langfuse/prompts.py,sha256=HO4Zy9usn5tKooBPCKksuw4Lff3c03Ny5wqn4ce_xZM,1217
77
+ sunholo/langfuse/prompts.py,sha256=EkbzSw9Jr05ULMsRDoGOp-frbtCZpnvdYSJEYNpzfX8,1293
76
78
  sunholo/llamaindex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
79
  sunholo/llamaindex/generate.py,sha256=l1Picr-hVwkmAUD7XmTCa63qY9ERliFHQXwyX3BqB2Q,686
78
80
  sunholo/llamaindex/get_files.py,sha256=6rhXCDqQ_lrIapISQ_OYQDjiSATXvS_9m3qq53-oIl0,781
79
- sunholo/llamaindex/import_files.py,sha256=DmBS4tTSZW39FhKGff0qjMTP07VO7xl-LaQuxQYoc8M,5888
81
+ sunholo/llamaindex/import_files.py,sha256=Iy_wkZCUSyrue_tAEHgnYaKDgg3-5GVygokHn3kd134,5747
80
82
  sunholo/lookup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
83
  sunholo/lookup/model_lookup.yaml,sha256=O7o-jP53MLA06C8pI-ILwERShO-xf6z_258wtpZBv6A,739
82
84
  sunholo/patches/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -91,7 +93,7 @@ sunholo/qna/parsers.py,sha256=Wn2X47_yeE39oeqxxgDr7jgBT-N1anYpJtVBq-623O4,2146
91
93
  sunholo/qna/retry.py,sha256=gFgOf9AxrZMIO9OwOYu1EW7rhNhyfnw_o4XAsNLBOVQ,2021
92
94
  sunholo/streaming/__init__.py,sha256=MpbydI2UYo_adttPQFkxNM33b-QRyNEbrKJx0C2AGPc,241
93
95
  sunholo/streaming/content_buffer.py,sha256=fWcg0oTf470M3U40VAChfmHmWRFgRD8VaT90jNfBCH0,6455
94
- sunholo/streaming/langserve.py,sha256=4AeNt4FPv461s20_5q17Nx83cHjK7Dl3gVOcWAxMgOk,6350
96
+ sunholo/streaming/langserve.py,sha256=Etbbo9crq4kXurgQtfG4p1yj_MwU5_KCYDINHS-tJl0,6507
95
97
  sunholo/streaming/stream_lookup.py,sha256=uTTUjf96mV7OCc-Sc8N09Fpu5g0T_mD_HbSzivtHMFQ,353
96
98
  sunholo/streaming/streaming.py,sha256=9z6pXINEopuL_Z1RnmgXAoZJum9dzyuOxqYtEYnjf8w,16405
97
99
  sunholo/summarise/__init__.py,sha256=MZk3dblUMODcPb1crq4v-Z508NrFIpkSWNf9FIO8BcU,38
@@ -101,8 +103,8 @@ sunholo/tools/web_browser.py,sha256=NgsAeVcndl-vMAbAfIzDJ8eRfCh5LDZan16OCNEKFmI,
101
103
  sunholo/utils/__init__.py,sha256=Hv02T5L2zYWvCso5hzzwm8FQogwBq0OgtUbN_7Quzqc,89
102
104
  sunholo/utils/api_key.py,sha256=Ct4bIAQZxzPEw14hP586LpVxBAVi_W9Serpy0BK-7KI,244
103
105
  sunholo/utils/big_context.py,sha256=gJIP7_ZL-YSLhOMq8jmFTMqH1wq8eB1NK7oKPeZAq2s,5578
104
- sunholo/utils/config.py,sha256=5lzO9CkLpDslp66ZwSBC_95aA1FQs-zpiOLi5YaYWbM,8907
105
- sunholo/utils/config_class.py,sha256=48zEohztqTb13PPYK9SLqWQtrperan-kCVizdhKg8_g,7647
106
+ sunholo/utils/config.py,sha256=Ute6SORPtkMnZy-BVVv0rtN28qSQ77GAzb7XtZGIAT0,8901
107
+ sunholo/utils/config_class.py,sha256=uyAsPXdxOY47CbQ8RifhUDL2BlxWP2QI-DIWBNlv6yk,8421
106
108
  sunholo/utils/config_schema.py,sha256=Wv-ncitzljOhgbDaq9qnFqH5LCuxNv59dTGDWgd1qdk,4189
107
109
  sunholo/utils/gcp.py,sha256=uueODEpA-P6O15-t0hmcGC9dONLO_hLfzSsSoQnkUss,4854
108
110
  sunholo/utils/gcp_project.py,sha256=0ozs6tzI4qEvEeXb8MxLnCdEVoWKxlM6OH05htj7_tc,1325
@@ -111,14 +113,13 @@ sunholo/utils/timedelta.py,sha256=BbLabEx7_rbErj_YbNM0MBcaFN76DC4PTe4zD2ucezg,49
111
113
  sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
112
114
  sunholo/utils/version.py,sha256=P1QAJQdZfT2cMqdTSmXmcxrD2PssMPEGM-WI6083Fck,237
113
115
  sunholo/vertex/__init__.py,sha256=XH7FUKxdIgN9H2iDcWxL3sRnVHC3297G24RqEn4Ob0Y,240
114
- sunholo/vertex/extensions.py,sha256=d-Ikt9gHFf-jUMPmyU-xHwYe22QtEyr90Ua1LDKgTws,11026
115
- sunholo/vertex/extensions_class.py,sha256=E0ix4YqFQG9EglKeTmp2-zwuZUA2crileGahAhe4g5k,12164
116
+ sunholo/vertex/extensions_class.py,sha256=4PsUM9dSYrIPpq9bZ3K2rL9MRb_rlqAgnMsW0o9gHck,15855
116
117
  sunholo/vertex/init.py,sha256=-w7b9GKsyJnAJpYHYz6_zBUtmeJeLXlEkgOfwoe4DEI,2715
117
- sunholo/vertex/memory_tools.py,sha256=WpedE5yDZcQiFOFBSOtwr-tRCnCXW9G6aZ01rFDfsMo,6862
118
+ sunholo/vertex/memory_tools.py,sha256=pomHrDKqvY8MZxfUqoEwhdlpCvSGP6KmFJMVKOimXjs,6842
118
119
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
119
- sunholo-0.72.0.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
120
- sunholo-0.72.0.dist-info/METADATA,sha256=I_2E5Z5Xq4rQQNgEIp4-WGtlsSXu0PHT2AbuOq8HjIs,6843
121
- sunholo-0.72.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
122
- sunholo-0.72.0.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
123
- sunholo-0.72.0.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
124
- sunholo-0.72.0.dist-info/RECORD,,
120
+ sunholo-0.73.3.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
121
+ sunholo-0.73.3.dist-info/METADATA,sha256=oZNyJJifnIAdT0EMyILv8u5vKUaR4lzyPUmNcXU9bvw,6909
122
+ sunholo-0.73.3.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
123
+ sunholo-0.73.3.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
124
+ sunholo-0.73.3.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
125
+ sunholo-0.73.3.dist-info/RECORD,,
@@ -1,326 +0,0 @@
1
- # https://cloud.google.com/vertex-ai/generative-ai/docs/extensions/create-extension
2
- # https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/extension#python
3
- from vertexai.preview import extensions
4
- from .init import init_vertex
5
- from ..logging import log
6
- from ..utils.gcp_project import get_gcp_project
7
- from ..utils.parsers import validate_extension_id
8
-
9
- # https://github.com/GoogleCloudPlatform/applied-ai-engineering-samples/blob/main/genai-on-vertex-ai/vertex_ai_extensions/notebooks/pandas_code_interpreter.ipynb
10
- import base64
11
- import json
12
- import pprint
13
- import pandas
14
- from io import StringIO
15
-
16
- global CODE_INTERPRETER_WRITTEN_FILES
17
- CODE_INTERPRETER_WRITTEN_FILES = []
18
-
19
- def get_extension_import_config(
20
- display_name: str,
21
- description: str,
22
- api_spec_gcs: dict,
23
- service_account_name: dict,
24
- tool_use_examples: list):
25
-
26
- tool_use_examples = [
27
- {
28
- "extensionOperation": {
29
- "operationId": "say_hello",
30
- },
31
- "displayName": "Say hello in the requested language",
32
- "query": "Say hello in French",
33
- "requestParams": {
34
- "fields": [
35
- {
36
- "key": "apiServicePrompt",
37
- "value": {
38
- "string_value": "French",
39
- }
40
- }
41
- ]
42
- },
43
- "responseParams": {
44
- "fields": [
45
- {
46
- "key": "apiServiceOutput",
47
- "value": {
48
- "string_value": "bonjour",
49
- },
50
- }
51
- ],
52
- },
53
- "responseSummary": "Bonjour"
54
- }
55
- ]
56
-
57
-
58
- return {
59
- "displayName": display_name,
60
- "description": description,
61
- "manifest": {
62
- "name": "EXTENSION_NAME_LLM",
63
- "description": "DESCRIPTION_LLM",
64
- "apiSpec": {
65
- "openApiGcsUri": api_spec_gcs,
66
- },
67
- "authConfig": {
68
- "authType": "OAUTH",
69
- "oauthConfig": {"service_account": service_account_name}
70
- }
71
- },
72
- "toolUseExamples": tool_use_examples,
73
- }
74
-
75
- # once an extension is available, call it in code here
76
- def create_extension_instance(
77
- display_name: str,
78
- description: str,
79
- open_api_gcs_uri: str,
80
- llm_name: str=None,
81
- llm_description: str=None,
82
- runtime_config: dict=None,
83
- service_account: str=None,
84
- ):
85
- """
86
- Args:
87
- - display_name: for the human. parsed to be used as extension_name
88
- - description: for the human
89
- - open_api_gcs_uri: location on GCS where open_ai yaml spec is
90
- - llm_name: for the model. If None, uses display_name
91
- - llm_description: for the model. If None, uses description
92
- - service_account: If not specified, the Vertex AI Extension Service Agent is used to execute the extension.
93
-
94
- """
95
- project_id = get_gcp_project()
96
- extension_name = f"projects/{project_id}/locations/us-central1/extensions/{validate_extension_id(display_name)}"
97
-
98
- extension = extensions.Extension.create(
99
- extension_name=extension_name,
100
- display_name=display_name,
101
- description=description,
102
- runtime_config=runtime_config or None,
103
- manifest={
104
- "name": llm_name or display_name,
105
- "description": llm_description or description,
106
- "api_spec": {
107
- "open_api_gcs_uri": open_api_gcs_uri
108
- },
109
- "auth_config": {
110
- "auth_type": "GOOGLE_SERVICE_ACCOUNT_AUTH",
111
- "google_service_account_config": service_account or {},
112
- },
113
- },
114
- )
115
- log.info(f"Created Vertex Extension: {extension_name}")
116
-
117
- return extension
118
-
119
-
120
-
121
- def create_extension_code_interpreter(
122
- code_artifacts_bucket=None
123
- ):
124
-
125
- # only us-central for now
126
- location = "us-central1"
127
- init_vertex(location=location)
128
-
129
- runtime_config=None
130
- if code_artifacts_bucket:
131
- runtime_config = {"codeInterpreterRuntimeConfig":
132
- {
133
- "fileInputGcsBucket": code_artifacts_bucket,
134
- "fileOutputGcsBucket": code_artifacts_bucket
135
- }
136
- }
137
-
138
- llm_description="""
139
- Tool to generate and execute valid Python code from a natural
140
- language description, or to execute custom Python code.
141
- Use this tool to:
142
- - generate and/or execute code for various tasks:
143
- - perform a wide variety of mathematical calculations, for example, add,
144
- subtract, multiply, divide, average, power, factorial, quotient,
145
- formulae, logarithms, random numbers, trigonometric functions, and
146
- equations;
147
- - sort, filter, select top results, and otherwise analyze data (including
148
- data acquired from other tools and Extensions);
149
- - create visualizations, plot charts, draw graphs, shapes, print results,
150
- etc.
151
- - execute custom code and get results and output files.
152
- """
153
-
154
- code_extension = create_extension_instance(
155
- display_name="Code Interpreter",
156
- description="This extension generates and executes code in the specified language",
157
- open_api_gcs_uri="gs://vertex-extension-public/code_interpreter.yaml",
158
- llm_name="code_interpreter_tool",
159
- llm_description=llm_description,
160
- runtime_config=runtime_config
161
- )
162
- log.info(f"Created code extension: {code_extension=}")
163
-
164
- return code_extension
165
-
166
- def execute_extension(operation_id: str,
167
- operation_params: dict,
168
- extension_id: str):
169
-
170
- # only us-central for now
171
- location = "us-central1"
172
- init_vertex(location=location)
173
-
174
- if not extension_id.startswith("projects/"):
175
- project_id=get_gcp_project()
176
- extension_name = f"projects/{project_id}/locations/{location}/extensions/{extension_id}"
177
- else:
178
- extension_name=extension_id
179
-
180
- extension = extensions.Extension(extension_name)
181
-
182
- response = extension.execute(
183
- operation_id=operation_id,
184
- # {"query": "find the max value in the list: [1,2,3,4,-5]"}
185
- operation_params=operation_params,
186
- )
187
-
188
- return response
189
-
190
- def execute_code_extension(query:str, filenames: list[str]=None, gcs_files: list[str]=None):
191
-
192
- if filenames and gcs_files:
193
- raise ValueError("Can't specify both filenames and gcs_files")
194
-
195
- extension_code_interpreter = extensions.Extension.from_hub("code_interpreter")
196
-
197
- file_arr=None
198
- if filenames:
199
- file_arr = [
200
- {
201
- "name": filename,
202
- "contents": base64.b64encode(open(filename, "rb").read()).decode()
203
- }
204
- for filename in filenames
205
- ]
206
-
207
- response = extension_code_interpreter.execute(
208
- operation_id = "generate_and_execute",
209
- operation_params={
210
- "query": query,
211
- "files": file_arr,
212
- "file_gcs_uris": gcs_files
213
- })
214
-
215
- CODE_INTERPRETER_WRITTEN_FILES.extend(
216
- [item['name'] for item in response['output_files']])
217
-
218
- if response.get('execution_error'):
219
- log.error(f"Code Execution Response failed with: {response.get('execution_error')} - maybe retry?")
220
-
221
- return response
222
-
223
- css_styles = """
224
- <style>
225
- .main_summary {
226
- font-weight: bold;
227
- font-size: 14px; color: #4285F4;
228
- background-color:rgba(221, 221, 221, 0.5); padding:8px;}
229
- </style>
230
- """
231
-
232
- # Parser to visualise the content of returned files as HTML.
233
- def parse_files_to_html(outputFiles, save_files_locally = True):
234
- IMAGE_FILE_EXTENSIONS = set(["jpg", "jpeg", "png"])
235
- file_list = []
236
- details_tml = """<details><summary>{name}</summary><div>{html_content}</div></details>"""
237
-
238
- if not outputFiles:
239
- return "No Files generated from the code"
240
- # Sort output_files so images are displayed before other files such as JSON.
241
- for output_file in sorted(
242
- outputFiles,
243
- key=lambda x: x["name"].split(".")[-1] not in IMAGE_FILE_EXTENSIONS,
244
- ):
245
- file_name = output_file.get("name")
246
- file_contents = base64.b64decode(output_file.get("contents"))
247
- if save_files_locally:
248
- open(file_name,"wb").write(file_contents)
249
-
250
- if file_name.split(".")[-1] in IMAGE_FILE_EXTENSIONS:
251
- # Render Image
252
- file_html_content = ('<img src="data:image/png;base64, '
253
- f'{output_file.get("contents")}" />')
254
- elif file_name.endswith(".json"):
255
- # Pretty print JSON
256
- json_pp = pprint.pformat(
257
- json.loads(file_contents.decode()),
258
- compact=False,
259
- width=160)
260
- file_html_content = (f'<span>{json_pp}</span>')
261
- elif file_name.endswith(".csv"):
262
- # CSV
263
- csv_md = pandas.read_csv(
264
- StringIO(file_contents.decode())).to_markdown(index=False)
265
- file_html_content = f'<span>{csv_md}</span>'
266
- elif file_name.endswith(".pkl"):
267
- # PKL
268
- file_html_content = f'<span>Preview N/A</span>'
269
- else:
270
- file_html_content = f"<span>{file_contents.decode()}</span>"
271
-
272
- file_list.append({'name': file_name, "html_content": file_html_content})
273
-
274
- buffer_html = [ details_tml.format(**_file) for _file in file_list ]
275
- return "".join(buffer_html)
276
-
277
- # Processing code interpreter response to html visualization.
278
- def process_response(response: dict, save_files_locally = None) -> None:
279
-
280
- result_template = """
281
- <details open>
282
- <summary class='main_summary'>{summary}:</summary>
283
- <div><pre>{content}</pre></div>
284
- </details>
285
- """
286
-
287
- result = ""
288
- code = response.get('generated_code')
289
- if 'execution_result' in response and response['execution_result']!="":
290
- result = result_template.format(
291
- summary="Executed Code Output",
292
- content=response.get('execution_result'))
293
- else:
294
- result = result_template.format(
295
- summary="Executed Code Output",
296
- content="Code does not produce printable output.")
297
-
298
- if response.get('execution_error', None):
299
- result += result_template.format(
300
- summary="Generated Code Raised a (Possibly Non-Fatal) Exception",
301
- content=response.get('execution_error', None))
302
-
303
- result += result_template.format(
304
- summary="Files Created <u>(Click on filename to view content)</u>",
305
- content=parse_files_to_html(
306
- response.get('output_files', []),
307
- save_files_locally = True))
308
-
309
- html_content = f"""
310
- {css_styles}
311
- <div id='main'>
312
- <div id="right">
313
- <h3>Generated Code by Code Interpreter</h3>
314
- <pre><code>{code}</code></pre>
315
- </div>
316
- <div id="left">
317
- <h3>Code Execution Results</h3>
318
- {result}
319
- </div>
320
- </div>
321
- """
322
- if save_files_locally:
323
- # write to local file
324
- pass
325
-
326
- return html_content