MilanM commited on
Commit
b5573a4
·
verified ·
1 Parent(s): d450cef

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +771 -356
app.py CHANGED
@@ -1,469 +1,884 @@
1
  import marimo
2
 
3
- __generated_with = "0.9.2"
4
- app = marimo.App()
5
 
6
 
7
  @app.cell
8
- def __():
9
  import marimo as mo
10
-
11
- mo.md("# Welcome to marimo! 🌊🍃")
12
- return (mo,)
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
 
15
  @app.cell
16
- def __(mo):
17
- slider = mo.ui.slider(1, 22)
18
- return (slider,)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
 
21
  @app.cell
22
- def __(mo, slider):
23
- mo.md(
24
- f"""
25
- marimo is a **reactive** Python notebook.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- This means that unlike traditional notebooks, marimo notebooks **run
28
- automatically** when you modify them or
29
- interact with UI elements, like this slider: {slider}.
30
 
31
- {"##" + "🍃" * slider.value}
32
- """
33
- )
 
 
 
 
34
  return
35
 
36
 
37
- @app.cell(hide_code=True)
38
- def __(mo):
39
- mo.accordion(
40
- {
41
- "Tip: disabling automatic execution": mo.md(
42
- rf"""
43
- marimo lets you disable automatic execution: just go into the
44
- notebook settings and set
45
 
46
- "Runtime > On Cell Change" to "lazy".
47
 
48
- When the runtime is lazy, after running a cell, marimo marks its
49
- descendants as stale instead of automatically running them. The
50
- lazy runtime puts you in control over when cells are run, while
51
- still giving guarantees about the notebook state.
52
- """
53
- )
54
- }
55
- )
56
  return
57
 
58
 
59
- @app.cell(hide_code=True)
60
- def __(mo):
61
- mo.md(
62
- """
63
- Tip: This is a tutorial notebook. You can create your own notebooks
64
- by entering `marimo edit` at the command line.
65
- """
66
- ).callout()
67
  return
68
 
69
 
70
- @app.cell(hide_code=True)
71
- def __(mo):
72
- mo.md(
73
- """
74
- ## 1. Reactive execution
 
 
75
 
76
- A marimo notebook is made up of small blocks of Python code called
77
- cells.
78
 
79
- marimo reads your cells and models the dependencies among them: whenever
80
- a cell that defines a global variable is run, marimo
81
- **automatically runs** all cells that reference that variable.
 
 
 
 
82
 
83
- Reactivity keeps your program state and outputs in sync with your code,
84
- making for a dynamic programming environment that prevents bugs before they
85
- happen.
86
- """
87
- )
 
 
88
  return
89
 
90
 
91
- @app.cell(hide_code=True)
92
- def __(changed, mo):
93
- (
94
- mo.md(
95
- f"""
96
- **✨ Nice!** The value of `changed` is now {changed}.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- When you updated the value of the variable `changed`, marimo
99
- **reacted** by running this cell automatically, because this cell
100
- references the global variable `changed`.
101
 
102
- Reactivity ensures that your notebook state is always
103
- consistent, which is crucial for doing good science; it's also what
104
- enables marimo notebooks to double as tools and apps.
105
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  )
107
- if changed
108
- else mo.md(
109
- """
110
- **🌊 See it in action.** In the next cell, change the value of the
111
- variable `changed` to `True`, then click the run button.
112
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  )
114
- )
115
- return
 
116
 
117
 
118
  @app.cell
119
- def __():
120
- changed = False
121
- return (changed,)
 
 
 
 
 
122
 
123
 
124
- @app.cell(hide_code=True)
125
- def __(mo):
126
- mo.accordion(
127
- {
128
- "Tip: execution order": (
129
- """
130
- The order of cells on the page has no bearing on
131
- the order in which cells are executed: marimo knows that a cell
132
- reading a variable must run after the cell that defines it. This
133
- frees you to organize your code in the way that makes the most
134
- sense for you.
135
- """
136
  )
137
- }
138
- )
139
- return
 
 
 
 
 
 
140
 
 
 
141
 
142
- @app.cell(hide_code=True)
143
- def __(mo):
144
- mo.md(
145
- """
146
- **Global names must be unique.** To enable reactivity, marimo imposes a
147
- constraint on how names appear in cells: no two cells may define the same
148
- variable.
149
- """
150
- )
151
- return
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- @app.cell(hide_code=True)
155
- def __(mo):
156
- mo.accordion(
157
- {
158
- "Tip: encapsulation": (
159
- """
160
- By encapsulating logic in functions, classes, or Python modules,
161
- you can minimize the number of global variables in your notebook.
162
- """
163
- )
164
- }
165
- )
166
- return
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
- @app.cell(hide_code=True)
170
- def __(mo):
171
- mo.accordion(
172
- {
173
- "Tip: private variables": (
174
- """
175
- Variables prefixed with an underscore are "private" to a cell, so
176
- they can be defined by multiple cells.
177
- """
 
 
 
 
 
 
 
 
 
 
 
178
  )
179
- }
180
- )
181
- return
182
 
183
 
184
- @app.cell(hide_code=True)
185
- def __(mo):
186
- mo.md(
187
- """
188
- ## 2. UI elements
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
- Cells can output interactive UI elements. Interacting with a UI
191
- element **automatically triggers notebook execution**: when
192
- you interact with a UI element, its value is sent back to Python, and
193
- every cell that references that element is re-run.
194
 
195
- marimo provides a library of UI elements to choose from under
196
- `marimo.ui`.
197
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  )
199
- return
 
 
200
 
201
 
202
  @app.cell
203
- def __(mo):
204
- mo.md("""**🌊 Some UI elements.** Try interacting with the below elements.""")
205
- return
 
 
 
206
 
207
 
208
  @app.cell
209
- def __(mo):
210
- icon = mo.ui.dropdown(["🍃", "🌊", "✨"], value="🍃")
211
- return (icon,)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
 
214
  @app.cell
215
- def __(icon, mo):
216
- repetitions = mo.ui.slider(1, 16, label=f"number of {icon.value}: ")
217
- return (repetitions,)
 
218
 
219
 
220
  @app.cell
221
- def __(icon, repetitions):
222
- icon, repetitions
223
- return
224
 
225
 
226
  @app.cell
227
- def __(icon, mo, repetitions):
228
- mo.md("# " + icon.value * repetitions.value)
229
- return
230
 
231
 
232
- @app.cell(hide_code=True)
233
- def __(mo):
234
- mo.md(
235
- """
236
- ## 3. marimo is just Python
237
 
238
- marimo cells parse Python (and only Python), and marimo notebooks are
239
- stored as pure Python files — outputs are _not_ included. There's no
240
- magical syntax.
241
 
242
- The Python files generated by marimo are:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
- - easily versioned with git, yielding minimal diffs
245
- - legible for both humans and machines
246
- - formattable using your tool of choice,
247
- - usable as Python scripts, with UI elements taking their default
248
- values, and
249
- - importable by other modules (more on that in the future).
250
- """
251
- )
252
- return
253
 
254
 
255
- @app.cell(hide_code=True)
256
- def __(mo):
257
- mo.md(
 
 
 
 
 
 
258
  """
259
- ## 4. Running notebooks as apps
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
- marimo notebooks can double as apps. Click the app window icon in the
262
- bottom-right to see this notebook in "app view."
 
263
 
264
- Serve a notebook as an app with `marimo run` at the command-line.
265
- Of course, you can use marimo just to level-up your
266
- notebooking, without ever making apps.
267
- """
268
- )
 
 
 
 
269
  return
270
 
271
 
272
- @app.cell(hide_code=True)
273
- def __(mo):
274
- mo.md(
275
- """
276
- ## 5. The `marimo` command-line tool
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
- **Creating and editing notebooks.** Use
279
 
280
- ```
281
- marimo edit
282
- ```
 
283
 
284
- in a terminal to start the marimo notebook server. From here
285
- you can create a new notebook or edit existing ones.
286
 
 
 
 
 
287
 
288
- **Running as apps.** Use
289
 
290
- ```
291
- marimo run notebook.py
292
- ```
 
293
 
294
- to start a webserver that serves your notebook as an app in read-only mode,
295
- with code cells hidden.
296
 
297
- **Convert a Jupyter notebook.** Convert a Jupyter notebook to a marimo
298
- notebook using `marimo convert`:
 
 
299
 
300
- ```
301
- marimo convert your_notebook.ipynb > your_app.py
302
- ```
303
 
304
- **Tutorials.** marimo comes packaged with tutorials:
 
 
 
305
 
306
- - `dataflow`: more on marimo's automatic execution
307
- - `ui`: how to use UI elements
308
- - `markdown`: how to write markdown, with interpolated values and
309
- LaTeX
310
- - `plots`: how plotting works in marimo
311
- - `sql`: how to use SQL
312
- - `layout`: layout elements in marimo
313
- - `fileformat`: how marimo's file format works
314
- - `markdown-format`: for using `.md` files in marimo
315
- - `for-jupyter-users`: if you are coming from Jupyter
316
 
317
- Start a tutorial with `marimo tutorial`; for example,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
319
- ```
320
- marimo tutorial dataflow
321
- ```
322
 
323
- In addition to tutorials, we have examples in our
324
- [our GitHub repo](https://www.github.com/marimo-team/marimo/tree/main/examples).
325
- """
326
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  return
328
 
329
 
330
- @app.cell(hide_code=True)
331
- def __(mo):
332
- mo.md(
333
- """
334
- ## 6. The marimo editor
335
-
336
- Here are some tips to help you get started with the marimo editor.
337
- """
338
- )
 
 
 
 
 
 
 
 
 
 
339
  return
340
 
341
 
342
  @app.cell
343
- def __(mo, tips):
344
- mo.accordion(tips)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  return
346
 
347
 
348
- @app.cell(hide_code=True)
349
- def __(mo):
350
- mo.md("""## Finally, a fun fact""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  return
352
 
353
 
354
- @app.cell(hide_code=True)
355
- def __(mo):
356
- mo.md(
357
- """
358
- The name "marimo" is a reference to a type of algae that, under
359
- the right conditions, clumps together to form a small sphere
360
- called a "marimo moss ball". Made of just strands of algae, these
361
- beloved assemblages are greater than the sum of their parts.
362
- """
363
- )
364
- return
365
 
366
 
367
- @app.cell(hide_code=True)
368
- def __():
369
- tips = {
370
- "Saving": (
371
- """
372
- **Saving**
373
-
374
- - _Name_ your app using the box at the top of the screen, or
375
- with `Ctrl/Cmd+s`. You can also create a named app at the
376
- command line, e.g., `marimo edit app_name.py`.
377
-
378
- - _Save_ by clicking the save icon on the bottom right, or by
379
- inputting `Ctrl/Cmd+s`. By default marimo is configured
380
- to autosave.
381
- """
382
- ),
383
- "Running": (
384
- """
385
- 1. _Run a cell_ by clicking the play ( ) button on the top
386
- right of a cell, or by inputting `Ctrl/Cmd+Enter`.
387
-
388
- 2. _Run a stale cell_ by clicking the yellow run button on the
389
- right of the cell, or by inputting `Ctrl/Cmd+Enter`. A cell is
390
- stale when its code has been modified but not run.
391
-
392
- 3. _Run all stale cells_ by clicking the play ( ▷ ) button on
393
- the bottom right of the screen, or input `Ctrl/Cmd+Shift+r`.
394
- """
395
- ),
396
- "Console Output": (
397
- """
398
- Console output (e.g., `print()` statements) is shown below a
399
- cell.
400
- """
401
- ),
402
- "Creating, Moving, and Deleting Cells": (
403
- """
404
- 1. _Create_ a new cell above or below a given one by clicking
405
- the plus button to the left of the cell, which appears on
406
- mouse hover.
407
-
408
- 2. _Move_ a cell up or down by dragging on the handle to the
409
- right of the cell, which appears on mouse hover.
410
-
411
- 3. _Delete_ a cell by clicking the trash bin icon. Bring it
412
- back by clicking the undo button on the bottom right of the
413
- screen, or with `Ctrl/Cmd+Shift+z`.
414
- """
415
- ),
416
- "Disabling Automatic Execution": (
417
- """
418
- Via the notebook settings (gear icon) or footer panel, you
419
- can disable automatic execution. This is helpful when
420
- working with expensive notebooks or notebooks that have
421
- side-effects like database transactions.
422
- """
423
- ),
424
- "Disabling Cells": (
425
- """
426
- You can disable a cell via the cell context menu.
427
- marimo will never run a disabled cell or any cells that depend on it.
428
- This can help prevent accidental execution of expensive computations
429
- when editing a notebook.
430
- """
431
- ),
432
- "Code Folding": (
433
- """
434
- You can collapse or fold the code in a cell by clicking the arrow
435
- icons in the line number column to the left, or by using keyboard
436
- shortcuts.
437
-
438
- Use the command palette (`Ctrl/Cmd+k`) or a keyboard shortcut to
439
- quickly fold or unfold all cells.
440
- """
441
- ),
442
- "Code Formatting": (
443
- """
444
- If you have [ruff](https://github.com/astral-sh/ruff) installed,
445
- you can format a cell with the keyboard shortcut `Ctrl/Cmd+b`.
446
- """
447
- ),
448
- "Command Palette": (
449
- """
450
- Use `Ctrl/Cmd+k` to open the command palette.
451
- """
452
- ),
453
- "Keyboard Shortcuts": (
454
- """
455
- Open the notebook menu (top-right) or input `Ctrl/Cmd+Shift+h` to
456
- view a list of all keyboard shortcuts.
457
- """
458
- ),
459
- "Configuration": (
460
- """
461
- Configure the editor by clicking the gears icon near the top-right
462
- of the screen.
463
- """
464
- ),
465
- }
466
- return (tips,)
467
 
468
 
469
  if __name__ == "__main__":
 
1
  import marimo
2
 
3
+ __generated_with = "0.13.4"
4
+ app = marimo.App(width="full")
5
 
6
 
7
  @app.cell
8
+ def _():
9
  import marimo as mo
10
+ from typing import Dict, Optional, List, Union, Any, Set
11
+ from ibm_watsonx_ai import APIClient, Credentials
12
+ from pathlib import Path
13
+ import pandas as pd
14
+ import mimetypes
15
+ import requests
16
+ import zipfile
17
+ import tempfile
18
+ import base64
19
+ import json
20
+ import glob
21
+ import ast
22
+ import re
23
+ import os
24
+ import io
25
+ return APIClient, Credentials, ast, io, mo, os, pd
26
 
27
 
28
  @app.cell
29
+ def _():
30
+ ### Loads baked in credentials if present
31
+ from baked_in_credentials.creds import credentials
32
+ from base_variables import wx_regions, wx_platform_url
33
+ ### Loads helper functions
34
+ from helper_functions.helper_functions import (
35
+ get_cred_value,
36
+ get_model_selection_table,
37
+ filter_models_by_function,
38
+ _enforce_model_selection,
39
+ update_max_tokens_limit,
40
+ get_key_by_value,
41
+ markdown_spacing,
42
+ load_file_dataframe,
43
+ create_parameter_table,
44
+ convert_table_to_json_docs,
45
+ get_cell_values,
46
+ wrap_with_spaces,
47
+ load_templates
48
+ )
49
+ ### Table Related Helper Functions
50
+ from helper_functions.table_helper_functions import (
51
+ append_llm_results_to_dataframe,
52
+ display_answers_as_markdown,
53
+ display_answers_stacked,
54
+ process_with_llm
55
+ )
56
+ return (
57
+ append_llm_results_to_dataframe,
58
+ convert_table_to_json_docs,
59
+ create_parameter_table,
60
+ credentials,
61
+ get_cell_values,
62
+ get_cred_value,
63
+ get_key_by_value,
64
+ get_model_selection_table,
65
+ load_file_dataframe,
66
+ load_templates,
67
+ process_with_llm,
68
+ wrap_with_spaces,
69
+ wx_regions,
70
+ )
71
 
72
 
73
  @app.cell
74
+ def _(credentials, get_cred_value, mo, wx_regions):
75
+ # Create a form with multiple elements
76
+ baked_in_creds = credentials
77
+ client_instantiation_form = (
78
+ mo.md('''
79
+ ###**watsonx.ai credentials:**
80
+
81
+ {wx_region}
82
+
83
+ {wx_api_key}
84
+
85
+ {project_id}
86
+
87
+ {space_id}
88
+ ''')
89
+ .batch(
90
+ wx_region = mo.ui.dropdown(
91
+ wx_regions,
92
+ label="Select your watsonx.ai region:",
93
+ value="US",
94
+ searchable=True
95
+ ),
96
+ wx_api_key = mo.ui.text(
97
+ placeholder="Add your IBM Cloud api-key...",
98
+ label="IBM Cloud Api-key:",
99
+ kind="password",
100
+ value=get_cred_value('api_key', creds_var_name='baked_in_creds')
101
+ ),
102
+ project_id = mo.ui.text(
103
+ placeholder="Add your watsonx.ai project_id...",
104
+ label="Project_ID:",
105
+ kind="text",
106
+ value=get_cred_value('project_id', creds_var_name='baked_in_creds')
107
+ ),
108
+ space_id = mo.ui.text(
109
+ placeholder="Add your watsonx.ai space_id...",
110
+ label="Space_ID:",
111
+ kind="text",
112
+ value=get_cred_value('space_id', creds_var_name='baked_in_creds')
113
+ )
114
+ ,)
115
+ .form(show_clear_button=True, bordered=False)
116
+ )
117
 
118
+ return (client_instantiation_form,)
 
 
119
 
120
+
121
+ @app.cell
122
+ def _(client_section, mo):
123
+ ui_accordion_section_1 = mo.accordion(
124
+ {"Section 1: **watsonx.ai Credentials**": client_section}
125
+ )
126
+ ui_accordion_section_1
127
  return
128
 
129
 
130
+ @app.cell
131
+ def _(file_uploader, mo):
132
+ ui_accordion_section_2 = mo.accordion(
133
+ {"Section 2: **File Loading**": file_uploader}
134
+ )
135
+ ui_accordion_section_2
136
+ return
 
137
 
 
138
 
139
+ @app.cell
140
+ def _(column_and_rows_sector, mo):
141
+ ui_accordion_section_3 = mo.accordion(
142
+ {"Section 3: **Column and Row Selection**": column_and_rows_sector}
143
+ )
144
+ ui_accordion_section_3
 
 
145
  return
146
 
147
 
148
+ @app.cell
149
+ def _(llm_setup, mo):
150
+ ui_accordion_section_4 = mo.accordion(
151
+ {"Section 4: **Model Setup**": llm_setup}
152
+ )
153
+ ui_accordion_section_4
 
 
154
  return
155
 
156
 
157
+ @app.cell
158
+ def _(mo, prompt_setup_stack):
159
+ ui_accordion_section_5 = mo.accordion(
160
+ {"Section 5: **Choose the Number of Prompts and Templates**": prompt_setup_stack}
161
+ )
162
+ ui_accordion_section_5
163
+ return
164
 
 
 
165
 
166
+ @app.cell
167
+ def _(mo, prompt_stack):
168
+ ui_accordion_section_6 = mo.accordion(
169
+ {"Section 6: **Prompt Setup**": prompt_stack}
170
+ )
171
+ ui_accordion_section_6
172
+ return
173
 
174
+
175
+ @app.cell
176
+ def _(mo, results_stack):
177
+ ui_accordion_section_7 = mo.accordion(
178
+ {"Section 7: **Run and View Results**": results_stack}
179
+ )
180
+ ui_accordion_section_7
181
  return
182
 
183
 
184
+ @app.cell
185
+ def _(client_instantiation_form, os):
186
+ if client_instantiation_form.value:
187
+ client_setup = client_instantiation_form.value
188
+ else:
189
+ client_setup = None
190
+
191
+ ### Extract Credential Variables:
192
+ if client_setup is not None:
193
+ wx_url = client_setup["wx_region"]
194
+ wx_api_key = client_setup["wx_api_key"]
195
+ os.environ["WATSONX_APIKEY"] = wx_api_key
196
+ project_id = client_setup.get("project_id")
197
+ space_id = client_setup.get("space_id")
198
+ else:
199
+ os.environ["WATSONX_APIKEY"] = ""
200
+ project_id = space_id = wx_api_key = wx_url = None
201
+ return client_setup, project_id, space_id, wx_api_key, wx_url
202
+
203
+
204
+ @app.cell
205
+ def _(
206
+ APIClient,
207
+ Credentials,
208
+ client_setup,
209
+ project_id,
210
+ space_id,
211
+ wx_api_key,
212
+ wx_url,
213
+ ):
214
+ if client_setup:
215
+ wx_credentials = Credentials(url=wx_url,
216
+ api_key=wx_api_key)
217
+
218
+ project_client = APIClient(credentials=wx_credentials,
219
+ project_id=project_id) if project_id else None
220
+
221
+ deployment_client = APIClient(credentials=wx_credentials,
222
+ space_id=space_id) if space_id else None
223
+
224
+ else:
225
+ wx_credentials = project_client = deployment_client = None
226
+ return deployment_client, project_client
227
+
228
+
229
+ @app.cell
230
+ def _(
231
+ client,
232
+ client_key,
233
+ client_options,
234
+ client_selector,
235
+ get_key_by_value,
236
+ mo,
237
+ wrap_with_spaces,
238
+ ):
239
+ active_client_name = get_key_by_value(client_options,client_key)
240
+ client_status = mo.md(f"### Client Instantiation Status will turn Green When Ready\n\n {client_selector}\n\n**Active Client:**{wrap_with_spaces(active_client_name, prefix_spaces=5)}")
241
+
242
+ client_callout_kind = "success" if client is not None else "neutral"
243
+ return client_callout_kind, client_status
244
+
245
+
246
+ @app.cell
247
+ def _(client_callout_kind, client_instantiation_form, client_status, mo):
248
+ client_callout = mo.callout(client_status, kind=client_callout_kind)
249
+
250
+ client_section = mo.hstack([client_instantiation_form, client_callout], align="center", justify="space-around")
251
+ return (client_section,)
252
+
253
+
254
+ @app.cell
255
+ def _(deployment_client, mo, project_client):
256
+ if project_client is not None and deployment_client is not None:
257
+ client_options = {"Project Client":project_client, "Deployment Client":deployment_client}
258
 
259
+ elif project_client is not None:
260
+ client_options = {"Project Client":project_client}
 
261
 
262
+ elif deployment_client is not None:
263
+ client_options = {"Deployment Client":deployment_client}
264
+
265
+ else:
266
+ client_options = {"No Client": "Instantiate a Client"}
267
+
268
+ default_client = next(iter(client_options))
269
+ client_selector = mo.ui.dropdown(client_options, value=default_client, label="**Switch your active client:**")
270
+ return client_options, client_selector
271
+
272
+
273
+ @app.cell
274
+ def _(client_selector):
275
+ client_key = client_selector.value
276
+ if client_key == "Instantiate a Client":
277
+ client = None
278
+ else:
279
+ client = client_key
280
+ return client, client_key
281
+
282
+
283
+ @app.cell
284
+ def _(mo):
285
+ file = mo.ui.file(
286
+ kind="area",
287
+ filetypes=[".xlsx", ".xls", ".csv", ".json"],
288
+ label="Upload a file (CSV, Excel, or JSON)"
289
  )
290
+ return (file,)
291
+
292
+
293
+ @app.cell
294
+ def _(file, io, mo, os, pd):
295
+ def get_file_extension(filename):
296
+ """Get the file extension from a filename."""
297
+ if not filename:
298
+ return None
299
+ return os.path.splitext(filename)[1].lower()
300
+
301
+ # Initialize variables
302
+ sheet_names = []
303
+ file_extension = None
304
+ excel_data = None
305
+
306
+ if file.contents():
307
+ file_extension = get_file_extension(file.name())
308
+
309
+ # Handle Excel files to get sheet names
310
+ if file_extension in ['.xlsx', '.xls']:
311
+ # For Excel files
312
+ excel_data = io.BytesIO(file.contents())
313
+ # Get sheet names without loading the data yet
314
+ sheet_names = pd.ExcelFile(excel_data).sheet_names
315
+
316
+ # Create sheet selector for Excel files
317
+ if file_extension in ['.xlsx', '.xls'] and sheet_names:
318
+ sheet_selector = mo.ui.dropdown(
319
+ options=sheet_names,
320
+ value=sheet_names[0],
321
+ label="Select Sheet:",
322
+ full_width=False,
323
+ searchable=True
324
  )
325
+ else:
326
+ sheet_selector = None
327
+ return excel_data, file_extension, sheet_selector
328
 
329
 
330
  @app.cell
331
+ def _(mo, table_dataframe_raw):
332
+ _ = table_dataframe_raw
333
+
334
+ if not table_dataframe_raw.empty:
335
+ apply_header_readjustment = mo.ui.checkbox(label="Activate Header Adjustment")
336
+ else:
337
+ apply_header_readjustment = None
338
+ return (apply_header_readjustment,)
339
 
340
 
341
+ @app.cell
342
+ def _(apply_header_readjustment, mo, sheet_selector, table_dataframe_raw):
343
+ _ = table_dataframe_raw
344
+
345
+ if not table_dataframe_raw.empty:
346
+ if apply_header_readjustment.value:
347
+ header_row = mo.ui.number(
348
+ label="Header Row index:",
349
+ value=0,
350
+ start=0,
351
+ stop=len(table_dataframe_raw)+1
 
352
  )
353
+ else:
354
+ header_row = mo.ui.number(
355
+ label="Header Row index:",
356
+ value=0,
357
+ start=0,
358
+ stop=0
359
+ )
360
+ else:
361
+ header_row = None
362
 
363
+ sheet_and_column_controls = mo.hstack([sheet_selector, apply_header_readjustment, header_row], gap=2, justify="space-around")
364
+ return header_row, sheet_and_column_controls
365
 
 
 
 
 
 
 
 
 
 
 
366
 
367
+ @app.cell
368
+ def _(file, mo, sheet_and_column_controls):
369
+ if file.name():
370
+ name_printout = mo.md(f"**{file.name()}**")
371
+ else:
372
+ name_printout = mo.md(f"No File Uploaded")
373
+
374
+ file_uploader = mo.vstack([file,name_printout, sheet_and_column_controls], justify="space-around", align="center")
375
+ return (file_uploader,)
376
+
377
+
378
+ @app.function
379
+ def apply_header_row(table_dataframe, header_row_value):
380
+ """
381
+ Set a specific row as the header for a dataframe.
382
+
383
+ Parameters:
384
+ -----------
385
+ table_dataframe : pd.DataFrame
386
+ The dataframe to modify
387
+ header_row_value : int
388
+ Row index to use as header (0-based)
389
+
390
+ Returns:
391
+ --------
392
+ tuple : (pd.DataFrame, list)
393
+ Modified dataframe with new headers and list of column names
394
+ """
395
+ if not table_dataframe.empty:
396
+ # Convert header row to column names
397
+ new_header = table_dataframe.iloc[header_row_value]
398
+ # Create new dataframe without the header row
399
+ new_df = table_dataframe.iloc[header_row_value+1:]
400
+ # Set the new header
401
+ new_df.columns = new_header
402
+ # Get list of column names
403
+ column_names = list(new_df.columns)
404
+ return new_df, column_names
405
+ return table_dataframe, []
406
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
 
408
+ @app.cell
409
+ def _(excel_data, file, file_extension, load_file_dataframe, sheet_selector):
410
+ table_dataframe_raw, table_column_names_raw = load_file_dataframe(file=file,
411
+ file_extension=file_extension,
412
+ sheet_selector=sheet_selector,
413
+ excel_data=excel_data)
414
+ return table_column_names_raw, table_dataframe_raw
415
+
416
+
417
+ @app.cell
418
+ def _(
419
+ apply_header_readjustment,
420
+ header_row,
421
+ table_column_names_raw,
422
+ table_dataframe_raw,
423
+ ):
424
+ if apply_header_readjustment is not None and apply_header_readjustment.value:
425
+ table_dataframe, table_column_names = apply_header_row(table_dataframe_raw, header_row_value=header_row.value if header_row is not None else 0)
426
+ else:
427
+ table_dataframe, table_column_names = table_dataframe_raw, table_column_names_raw
428
+ return table_column_names, table_dataframe
429
 
430
+
431
+ @app.cell
432
+ def _(mo, pd, table_column_names, table_dataframe):
433
+ _ = table_dataframe
434
+
435
+ if not table_dataframe.empty:
436
+ center_column_text = {col: "center" for col in table_column_names}
437
+ table = mo.ui.table(table_dataframe,
438
+ initial_selection=[0],
439
+ wrapped_columns=table_column_names,
440
+ text_justify_columns=center_column_text,
441
+ label="**Select the Rows to Process**")
442
+ else:
443
+ table = (
444
+ mo.md('''###**No data available in the uploaded file**''')
445
+ .batch(upload_a_file = mo.ui.table(data=pd.DataFrame(
446
+ {"Upload File":"No File"},
447
+ index=[0])
448
+ )
449
+ )
450
  )
451
+ return (table,)
 
 
452
 
453
 
454
+ @app.cell
455
+ def _(create_parameter_table, table_column_names, table_dataframe):
456
+ _ = table_dataframe
457
+
458
+ if not table_dataframe.empty:
459
+ column_selector = create_parameter_table(
460
+ label="Select the Columns to Process",
461
+ input_list=table_column_names,
462
+ column_name="Column Options",
463
+ selection_type="multi-cell",
464
+ text_justify="center"
465
+ )
466
+ else:
467
+ column_selector = create_parameter_table(
468
+ label="Select the Columns to Process",
469
+ input_list=[],
470
+ column_name="Column Options",
471
+ selection_type="multi-cell",
472
+ text_justify="center"
473
+ )
474
+
475
+ return (column_selector,)
476
 
 
 
 
 
477
 
478
+ @app.cell
479
+ def _(column_selector, get_cell_values):
480
+ columns_to_use = get_cell_values(column_selector)
481
+ return (columns_to_use,)
482
+
483
+
484
+ @app.cell
485
+ def _(column_selector, mo, table):
486
+ column_and_rows_sector = mo.vstack([column_selector, table], align="stretch", justify="start")
487
+ return (column_and_rows_sector,)
488
+
489
+
490
+ @app.cell
491
+ def _(columns_to_use, convert_table_to_json_docs, pd, table):
492
+ if table.value is not None:
493
+ selected_rows = table.value
494
+ fields_to_process = convert_table_to_json_docs(selected_rows, selected_columns=columns_to_use)
495
+ else:
496
+ selected_rows = pd.DataFrame([])
497
+ fields_to_process = []
498
+ return fields_to_process, selected_rows
499
+
500
+
501
+ @app.cell
502
+ def _(client, get_model_selection_table):
503
+ if client is not None:
504
+ model_selector, resources, model_id_list = get_model_selection_table(client=client,
505
+ model_type="chat",
506
+ filter_functionality=None,
507
+ selection_mode="single-cell"
508
+ )
509
+ else:
510
+ model_selector = get_model_selection_table(client=None, selection_mode="single-cell")
511
+ resources = model_id_list = None
512
+ return (model_selector,)
513
+
514
+
515
+ @app.cell
516
+ def _(mo, model_selector):
517
+ from ibm_watsonx_ai.foundation_models import ModelInference
518
+ from ibm_watsonx_ai.metanames import GenTextParamsMetaNames as GenParams
519
+ # Create a form with multiple elements
520
+ llm_parameters = (
521
+ mo.md('''
522
+ ###**LLM parameters:**
523
+
524
+ {decoding_method}
525
+
526
+ {repetition_penalty}
527
+
528
+ {min_tokens}
529
+
530
+ {max_tokens}
531
+
532
+ {stop_sequences}
533
+ ''')
534
+ .batch(
535
+ ### Preset Options
536
+ decoding_method = mo.ui.dropdown(options=["greedy", "sample"], value="greedy",label="Decoding Method:"),
537
+ min_tokens = mo.ui.number(start=1, stop=1, label="Minimum Output Tokens:"),
538
+ max_tokens = mo.ui.number(start=1, stop=8096, value=500, label="Maximum Output Tokens:"),
539
+ repetition_penalty = mo.ui.number(start=1.0, stop=2.0, step=0.01, label="Repetition Penalty:"),
540
+ stop_sequences = mo.ui.text(label="Stopping Sequences:", value="['<|end_of_text|>','</s>']", placeholder="List of Strings, e.g. ['<|end_of_text|>','</s>']", full_width=False)
541
+ )
542
  )
543
+
544
+ llm_setup = mo.hstack([model_selector, llm_parameters], align="center", justify="space-around")
545
+ return GenParams, ModelInference, llm_parameters, llm_setup
546
 
547
 
548
  @app.cell
549
+ def _(model_selector):
550
+ if model_selector.value:
551
+ selected_model = model_selector.value[0]['value']
552
+ else:
553
+ selected_model = "mistralai/mistral-large"
554
+ return (selected_model,)
555
 
556
 
557
  @app.cell
558
+ def _(GenParams, ModelInference, ast, client, llm_parameters, selected_model):
559
+ if llm_parameters.value:
560
+ params = {
561
+ GenParams.DECODING_METHOD: llm_parameters.value['decoding_method'],
562
+ GenParams.MAX_NEW_TOKENS: llm_parameters.value['max_tokens'],
563
+ GenParams.MIN_NEW_TOKENS: llm_parameters.value['min_tokens'],
564
+ GenParams.REPETITION_PENALTY: llm_parameters.value['repetition_penalty'],
565
+ GenParams.STOP_SEQUENCES: ast.literal_eval(llm_parameters.value['stop_sequences']),
566
+ GenParams.RETURN_OPTIONS: {
567
+ 'input_text': False,
568
+ 'generated_tokens': False,
569
+ 'input_tokens': True,
570
+ 'token_logprobs': False
571
+ }
572
+ }
573
+ else:
574
+ params = {}
575
+
576
+ if client:
577
+ inf_model = ModelInference(api_client=client, model_id=selected_model, params=params)
578
+ else:
579
+ inf_model = None
580
+ return inf_model, params
581
 
582
 
583
  @app.cell
584
+ def _(load_templates):
585
+ template_folder = "./prompt_templates"
586
+ templates = load_templates(template_folder)
587
+ return (templates,)
588
 
589
 
590
  @app.cell
591
+ def _(mo):
592
+ prompt_number_slider = mo.ui.slider(start=1, stop=5, value=1, step=1, label="Prompt Templates", show_value=True)
593
+ return (prompt_number_slider,)
594
 
595
 
596
  @app.cell
597
+ def _(mo, prompt_number_slider, template_selector_stack):
598
+ prompt_setup_stack = mo.hstack([prompt_number_slider, template_selector_stack], justify="space-around")
599
+ return (prompt_setup_stack,)
600
 
601
 
602
+ @app.cell
603
+ def _(mo):
604
+ get_pt_state, set_pt_state = mo.state(None)
605
+ return get_pt_state, set_pt_state
 
606
 
 
 
 
607
 
608
+ @app.cell
609
+ def _(mo, prompt_number_slider, set_pt_state, templates):
610
+ def update_state_from_templates(value):
611
+ # Get current values from all template selectors
612
+ template_values = [selector.value for selector in template_selectors]
613
+
614
+ # Update the state with the list of values
615
+ set_pt_state(template_values)
616
+
617
+ # Return the list of values
618
+ return template_values
619
+
620
+ def create_template_dropdowns(num=1):
621
+ return mo.ui.dropdown(
622
+ options=templates,
623
+ label=f"**Select Prompt {num} Template with Syntax:**",
624
+ value="empty",
625
+ on_change=update_state_from_templates
626
+ )
627
 
628
+ template_selectors = [create_template_dropdowns(i) for i in range(1, prompt_number_slider.value+1)]
629
+ template_selector_stack = mo.hstack(template_selectors, wrap=True, justify="start")
630
+ return (template_selector_stack,)
 
 
 
 
 
 
631
 
632
 
633
+ @app.cell
634
+ def _(fields_to_process, mo, prompt_number_slider):
635
+ if fields_to_process:
636
+ variable_names = [key for key in fields_to_process[0].keys()
637
+ if key != "_marimo_row_id" and key != "upload_a_file"]
638
+ else:
639
+ variable_names = []
640
+
641
+ def create_stats_from_variables(variable_names):
642
  """
643
+ Creates mo.stat objects for each variable name in the list.
644
+ Labels are formatted as "Column Variable Tag: {index+1}"
645
+ Values display the variable name itself.
646
+ """
647
+ stats = []
648
+
649
+ for i, var_name in enumerate(variable_names):
650
+ stat = mo.stat(
651
+ value=f"{{{var_name}}}",
652
+ label=f"Column Variable Tag {i+1}",
653
+ bordered=True
654
+ )
655
+ stats.append(stat)
656
+
657
+ return mo.sidebar(stats, width="525")
658
 
659
+ def is_disabled(button_num):
660
+ return prompt_number_slider.value < button_num
661
+ return create_stats_from_variables, is_disabled, variable_names
662
 
663
+
664
+ @app.cell
665
+ def _(create_stats_from_variables, variable_names):
666
+ if variable_names:
667
+ prompt_input_variables = create_stats_from_variables(variable_names)
668
+ else:
669
+ prompt_input_variables = None
670
+
671
+ prompt_input_variables
672
  return
673
 
674
 
675
+ @app.cell
676
+ def _(get_pt_state, mo, prompt_number_slider):
677
+ def create_prompt(num=1):
678
+ # Wrap in a function to create reactive dependency on state
679
+ def get_template_content(num=1):
680
+ content = get_pt_state()[num-1] if get_pt_state() and num-1 < len(get_pt_state()) else "empty"
681
+ return content
682
+
683
+ prompt_column_label = mo.ui.text(label=f"**Add output column name for Prompt {num}:**", value=f"Added Column {num}")
684
+ prompt_editor = mo.ui.code_editor(value=get_template_content(num), language="python", min_height=300, theme="dark")
685
+
686
+ return [
687
+ prompt_column_label,
688
+ prompt_editor
689
+ ]
690
+
691
+ prompts_raw = [create_prompt(i) for i in range(1, prompt_number_slider.value+1)]
692
+ return (prompts_raw,)
693
 
 
694
 
695
+ @app.cell
696
+ def _(is_disabled, mo):
697
+ run_prompt_button_1 = mo.ui.run_button(label="Run Prompt 1", disabled=is_disabled(1))
698
+ return (run_prompt_button_1,)
699
 
 
 
700
 
701
+ @app.cell
702
+ def _(is_disabled, mo):
703
+ run_prompt_button_2 = mo.ui.run_button(label="Run Prompt 2", disabled=is_disabled(2))
704
+ return (run_prompt_button_2,)
705
 
 
706
 
707
+ @app.cell
708
+ def _(is_disabled, mo):
709
+ run_prompt_button_3 = mo.ui.run_button(label="Run Prompt 3", disabled=is_disabled(3))
710
+ return (run_prompt_button_3,)
711
 
 
 
712
 
713
+ @app.cell
714
+ def _(is_disabled, mo):
715
+ run_prompt_button_4 = mo.ui.run_button(label="Run Prompt 4", disabled=is_disabled(4))
716
+ return (run_prompt_button_4,)
717
 
 
 
 
718
 
719
+ @app.cell
720
+ def _(is_disabled, mo):
721
+ run_prompt_button_5 = mo.ui.run_button(label="Run Prompt 5", disabled=is_disabled(5))
722
+ return (run_prompt_button_5,)
723
 
 
 
 
 
 
 
 
 
 
 
724
 
725
+ @app.cell
726
+ def _(
727
+ append_llm_results_to_dataframe,
728
+ fields_to_process,
729
+ inf_model,
730
+ params,
731
+ process_with_llm,
732
+ prompts_raw,
733
+ results_table,
734
+ run_prompt_button_1,
735
+ selected_rows,
736
+ ):
737
+ if run_prompt_button_1.value:
738
+ prompt_answers_1 = process_with_llm(fields_to_process=fields_to_process,
739
+ prompt_template=prompts_raw[0][1].value,
740
+ inf_model=inf_model, params=params, batch_size=10)
741
+ append_llm_results_to_dataframe(target_dataframe=results_table, fields_to_process=fields_to_process, llm_results=prompt_answers_1, selection_table=selected_rows, column_name=prompts_raw[0][0].value)
742
+ else:
743
+ prompt_answers_1 = []
744
+ return
745
 
 
 
 
746
 
747
+ @app.cell
748
+ def _(
749
+ append_llm_results_to_dataframe,
750
+ fields_to_process,
751
+ inf_model,
752
+ params,
753
+ process_with_llm,
754
+ prompts_raw,
755
+ results_table,
756
+ run_prompt_button_2,
757
+ selected_rows,
758
+ ):
759
+ if run_prompt_button_2.value:
760
+ prompt_answers_2 = process_with_llm(fields_to_process=fields_to_process,
761
+ prompt_template=prompts_raw[1][1].value,
762
+ inf_model=inf_model, params=params, batch_size=10)
763
+ append_llm_results_to_dataframe(target_dataframe=results_table, fields_to_process=fields_to_process, llm_results=prompt_answers_2, selection_table=selected_rows, column_name=prompts_raw[1][0].value)
764
+ else:
765
+ prompt_answers_2 = []
766
  return
767
 
768
 
769
+ @app.cell
770
+ def _(
771
+ append_llm_results_to_dataframe,
772
+ fields_to_process,
773
+ inf_model,
774
+ params,
775
+ process_with_llm,
776
+ prompts_raw,
777
+ results_table,
778
+ run_prompt_button_3,
779
+ selected_rows,
780
+ ):
781
+ if run_prompt_button_3.value:
782
+ prompt_answers_3 = process_with_llm(fields_to_process=fields_to_process,
783
+ prompt_template=prompts_raw[2][1].value,
784
+ inf_model=inf_model, params=params, batch_size=10)
785
+ append_llm_results_to_dataframe(target_dataframe=results_table, fields_to_process=fields_to_process, llm_results=prompt_answers_3, selection_table=selected_rows, column_name=prompts_raw[2][0].value)
786
+ else:
787
+ prompt_answers_3 = []
788
  return
789
 
790
 
791
  @app.cell
792
+ def _(
793
+ append_llm_results_to_dataframe,
794
+ fields_to_process,
795
+ inf_model,
796
+ params,
797
+ process_with_llm,
798
+ prompts_raw,
799
+ results_table,
800
+ run_prompt_button_4,
801
+ selected_rows,
802
+ ):
803
+ if run_prompt_button_4.value:
804
+ prompt_answers_4 = process_with_llm(fields_to_process=fields_to_process,
805
+ prompt_template=prompts_raw[3][1].value,
806
+ inf_model=inf_model, params=params, batch_size=10)
807
+ append_llm_results_to_dataframe(target_dataframe=results_table, fields_to_process=fields_to_process, llm_results=prompt_answers_4, selection_table=selected_rows, column_name=prompts_raw[3][0].value)
808
+ else:
809
+ prompt_answers_4 = []
810
  return
811
 
812
 
813
+ @app.cell
814
+ def _(
815
+ append_llm_results_to_dataframe,
816
+ fields_to_process,
817
+ inf_model,
818
+ params,
819
+ process_with_llm,
820
+ prompts_raw,
821
+ results_table,
822
+ run_prompt_button_5,
823
+ selected_rows,
824
+ ):
825
+ if run_prompt_button_5.value:
826
+ prompt_answers_5 = process_with_llm(fields_to_process=fields_to_process,
827
+ prompt_template=prompts_raw[4][1].value,
828
+ inf_model=inf_model, params=params, batch_size=10)
829
+ append_llm_results_to_dataframe(target_dataframe=results_table, fields_to_process=fields_to_process, llm_results=prompt_answers_5, selection_table=selected_rows,column_name=prompts_raw[4][0].value)
830
+ else:
831
+ prompt_answers_5 = []
832
  return
833
 
834
 
835
+ @app.cell
836
+ def _(table_dataframe):
837
+ _ = table_dataframe
838
+
839
+ if not table_dataframe.empty:
840
+ results_table = table_dataframe.copy()
841
+ else:
842
+ results_table = []
843
+ return (results_table,)
 
 
844
 
845
 
846
+ @app.cell
847
+ def _(
848
+ mo,
849
+ results_table,
850
+ run_prompt_button_1,
851
+ run_prompt_button_2,
852
+ run_prompt_button_3,
853
+ run_prompt_button_4,
854
+ run_prompt_button_5,
855
+ ):
856
+ if run_prompt_button_1.value or run_prompt_button_2.value or run_prompt_button_3.value or run_prompt_button_4.value or run_prompt_button_5.value:
857
+ results_table_view = mo.ui.table(results_table)
858
+ else:
859
+ results_table_view = mo.ui.table(results_table)
860
+ return (results_table_view,)
861
+
862
+ @app.cell
863
+ def _(mo, prompts_raw):
864
+ prompts = [mo.vstack([prompt[0], prompt[1]]) for prompt in prompts_raw]
865
+ prompt_stack = mo.vstack(prompts, heights="equal", align="stretch", justify="space-around", gap=3)
866
+ return (prompt_stack,)
867
+
868
+
869
+ @app.cell
870
+ def _(
871
+ mo,
872
+ results_table_view,
873
+ run_prompt_button_1,
874
+ run_prompt_button_2,
875
+ run_prompt_button_3,
876
+ run_prompt_button_4,
877
+ run_prompt_button_5,
878
+ ):
879
+ run_button_stack = mo.hstack([run_prompt_button_1,run_prompt_button_2,run_prompt_button_3,run_prompt_button_4,run_prompt_button_5])
880
+ results_stack = mo.vstack([run_button_stack,results_table_view])
881
+ return (results_stack,)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
882
 
883
 
884
  if __name__ == "__main__":