simian-examples 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ include simian/examples/js/treemap.js
2
+ include simian/examples/logo.png
3
+ include simian/examples/treemap.json
4
+ include simian/examples/workshop_example.json
5
+ include simian/version.txt
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: simian-examples
3
+ Version: 3.3.0
4
+ Summary: Simian Examples for Python
5
+ Author-email: "MonkeyProof Solutions B.V." <info@simiansuite.com>
6
+ License-Expression: MIT
7
+ Project-URL: homepage, https://simiansuite.com
8
+ Project-URL: documentation, https://doc.simiansuite.com/simian-gui/index.html
9
+ Project-URL: releasenotes, https://doc.simiansuite.com/simian-gui/release_notes.html
10
+ Project-URL: issues, https://github.com/Simian-Web-Apps/Issue-Tracker
11
+ Project-URL: github, https://github.com/Simian-Web-Apps
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: Implementation :: CPython
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: Unix
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: simian-gui==3.3.0
20
+ Requires-Dist: scipy
21
+ Provides-Extra: local
22
+ Requires-Dist: simian-local==3.3.0; extra == "local"
23
+ Dynamic: provides-extra
24
+ Dynamic: requires-dist
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools", "build"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "simian-examples"
7
+ authors = [
8
+ { name = "MonkeyProof Solutions B.V.", email = "info@simiansuite.com" },
9
+ ]
10
+ description = "Simian Examples for Python"
11
+ requires-python = ">= 3.10"
12
+ dynamic = ["version", "dependencies", "optional-dependencies"]
13
+ license = "MIT"
14
+
15
+ # From https://pypi.org/classifiers/
16
+ classifiers = [
17
+ 'Development Status :: 5 - Production/Stable',
18
+ 'Intended Audience :: Developers',
19
+ 'Programming Language :: Python :: 3 :: Only',
20
+ 'Programming Language :: Python :: Implementation :: CPython',
21
+ 'Operating System :: Microsoft :: Windows',
22
+ # 'Operating System :: POSIX',
23
+ 'Operating System :: Unix',
24
+ # 'Operating System :: MacOS',
25
+ ]
26
+
27
+ # Register useful URLs.
28
+ urls.homepage = "https://simiansuite.com"
29
+ urls.documentation = "https://doc.simiansuite.com/simian-gui/index.html"
30
+ urls.releasenotes = "https://doc.simiansuite.com/simian-gui/release_notes.html"
31
+ urls.issues = "https://github.com/Simian-Web-Apps/Issue-Tracker"
32
+ urls.github = "https://github.com/Simian-Web-Apps"
33
+
34
+
35
+ [tool.ruff]
36
+ line-length = 100
37
+
38
+ [tool.setuptools]
39
+ include-package-data = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,17 @@
1
+ """Setup Simian Examples."""
2
+
3
+ import os
4
+
5
+ from setuptools import setup
6
+
7
+
8
+ version = os.environ.get("CI_COMMIT_TAG", "3.dev1")
9
+
10
+ setup(
11
+ version=version,
12
+ install_requires=[
13
+ f"simian-gui=={version}",
14
+ "scipy",
15
+ ],
16
+ extras_require={"local": [f"simian-local=={version}"]},
17
+ )
@@ -0,0 +1,408 @@
1
+ """App containing all component types."""
2
+
3
+ from pathlib import Path
4
+
5
+ import numpy as np
6
+ from simian.gui import Form, component, utils
7
+
8
+ COMPONENTS_LEVEL = 1
9
+
10
+
11
+ if __name__ == "__main__":
12
+ # Run as a script
13
+ from simian.entrypoint import assert_simian_gui_imports
14
+
15
+ assert_simian_gui_imports()
16
+ from simian.local import run
17
+
18
+ run("simian.examples.all_components", size=[1280, 720], window_title="All Components Example")
19
+
20
+
21
+ def gui_init(_):
22
+ """Initialize form with components."""
23
+ # Initialize the form.
24
+ form = Form()
25
+
26
+ # Generate all component types.
27
+ build_list = _generate_components_with_type(COMPONENTS_LEVEL)
28
+ col_opts = {"width": 6}
29
+
30
+ # Build the form.
31
+ created_components = utils.addComponentsFromTable(
32
+ parent=form,
33
+ build_table=[
34
+ # key class lvl options default label tooltip
35
+ ["columns", "Columns", 1, None, None, None, None],
36
+ ["left_column", "column", 2, col_opts, None, None, None],
37
+ ["selector", "Select", 3, None, None, "Select component type", "Choose the component type that you want to see."],
38
+ ["right_column", "column", 2, col_opts, None, None, None], # fmt: skip
39
+ ],
40
+ )
41
+ # Put all generated root components in the options list of the component selector.
42
+ created_components["selector"].setValues(
43
+ [c[5] for c in build_list if c[2] == COMPONENTS_LEVEL and c[5] is not None],
44
+ [c[0] for c in build_list if c[2] == COMPONENTS_LEVEL and c[5] is not None],
45
+ )
46
+
47
+ # Add the components to the right column.
48
+ utils.addComponentsFromTable(created_components["right_column"], build_list)
49
+
50
+ # Define the logo.
51
+ image_file = str(Path(__file__).parent / "logo.png")
52
+ logo = utils.encodeImage(image_file)
53
+
54
+ return {
55
+ "form": form,
56
+ "navbar": {
57
+ "title": "All Components Example",
58
+ "subtitle": "<small>Simian Demo</small>",
59
+ "logo": logo,
60
+ },
61
+ }
62
+
63
+
64
+ def gui_event(_, payload):
65
+ """Handle events."""
66
+ return payload
67
+
68
+
69
+ def _generate_components_with_type(base_level: int) -> list:
70
+ """Create a list with instances of all subclasses of Component."""
71
+ classes = component.Component.__subclasses__()
72
+ classes.extend(component.Html.__subclasses__())
73
+ class_names = [cls.__name__ for cls in classes]
74
+
75
+ # We do not support the Address component and it is undocumented. See issue #216.
76
+ address_idx = class_names.index("Address")
77
+ class_names.pop(address_idx)
78
+ classes.pop(address_idx)
79
+
80
+ # Do not show the Builder as a component.
81
+ builder_idx = class_names.index("Builder")
82
+ class_names.pop(builder_idx)
83
+ classes.pop(builder_idx)
84
+
85
+ sort_order = np.argsort(class_names)
86
+
87
+ # Initialize the buildTable.
88
+ build_array = []
89
+
90
+ # Add a row for each class.
91
+ for class_idx in sort_order:
92
+ if class_names[class_idx] in ["Form", "Container"]:
93
+ # Exclude Form - it is not relevant for this example.
94
+ continue
95
+
96
+ constructor = classes[class_idx]
97
+ label = class_names[class_idx]
98
+ tester = constructor(label + str(base_level))
99
+ default_value = _get_default_value(tester.key)
100
+ opts = _get_options(tester.key)
101
+
102
+ if base_level == COMPONENTS_LEVEL:
103
+ # Top-level: add conditional to show the component.
104
+ cond_opts = {"conditional": {"show": True, "when": "selector", "eq": tester.key}}
105
+
106
+ if opts:
107
+ opts.update(cond_opts)
108
+ else:
109
+ opts = cond_opts
110
+
111
+ doc = _get_doc(label)
112
+ doc_link = f'<p><small><a href="{doc}" target="_blank"><i class="fa fa-book"></i> Documentation</a></small></p>'
113
+ build_array.append(
114
+ [tester.key + "Doc", "Html", base_level, cond_opts, doc_link, None, None]
115
+ )
116
+
117
+ build_array.append([tester.key, tester.type, base_level, opts, default_value, label, None])
118
+
119
+ if base_level == COMPONENTS_LEVEL:
120
+ # Top-level: add components to capable classes.
121
+ if tester.hasComponents():
122
+ # Add components: some special cases.
123
+ if tester.type == "address":
124
+ # Not possible to add components, even though it has a components field.
125
+ pass
126
+ elif tester.type == "tabs":
127
+ # Only tabs can be added - but they are stored in the components field...
128
+ build_array.extend(
129
+ [
130
+ [tester.key + "tab1", "tab", base_level + 1, None, None, "Tab 1", None],
131
+ [tester.key + "tab1dummy", "textfield", base_level + 2, None, None, "Text Field", None],
132
+ ]
133
+ ) # fmt: skip
134
+ build_array.extend(
135
+ [
136
+ [tester.key + "tab2", "tab", base_level + 1, None, None, "Tab 2", None],
137
+ [tester.key + "tab2dummy", "textfield", base_level + 2, None, None, "Text Field", None],
138
+ ]
139
+ ) # fmt: skip
140
+ else:
141
+ # Panel, Container, etc.
142
+ build_array.extend(_add_subcomponents(tester.key))
143
+ elif tester.type == "columns":
144
+ # Columns are not stored in the components field.
145
+ build_array.extend(
146
+ [
147
+ [tester.key + "col1", "column", base_level + 1, {"width": 9}, None, None, None],
148
+ [tester.key + "col1dummy", "textfield", base_level + 2, None, None, "Text Field", None],
149
+ ]
150
+ ) # fmt: skip
151
+ build_array.extend(
152
+ [
153
+ [tester.key + "col2", "column", base_level + 1, {"width": 3}, None, None, None],
154
+ [tester.key + "col2dummy", "textfield", base_level + 2, None, None, "Text Field", None],
155
+ ]
156
+ ) # fmt: skip
157
+ elif tester.type == "table":
158
+ for r in range(2):
159
+ build_array.append(
160
+ [f"{tester.key}row{r}", "tablerow", base_level + 1, None, None, None, None]
161
+ )
162
+ for c in range(2):
163
+ build_array.extend(
164
+ [
165
+ [f"{tester.key}cell{r}{c}", "tablecell", base_level + 2, None, None, None, None],
166
+ [f"{tester.key}comp{r}{c}", "textfield", base_level + 3, None, None, None, None],
167
+ ]
168
+ ) # fmt: skip
169
+
170
+ return build_array
171
+
172
+
173
+ def _get_default_value(component_key: str):
174
+ return _get_default_values().get(component_key)
175
+
176
+
177
+ def _get_default_values():
178
+ return {
179
+ "Address1": {
180
+ "place_id": 26591519,
181
+ "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
182
+ "osm_type": "node",
183
+ "osm_id": 2735607631,
184
+ "boundingbox": ["51.573239", "51.573339", "4.8052079", "4.8053079"],
185
+ "lat": "51.573289",
186
+ "lon": "4.8052579",
187
+ "display_name": "71, Groot Ypelaardreef, Breda, North Brabant, Netherlands, 4834 HC, Netherlands",
188
+ "class": "place",
189
+ "type": "house",
190
+ "importance": 0.4200999999999999,
191
+ "address": {
192
+ "house_number": "71",
193
+ "road": "Groot Ypelaardreef",
194
+ "city": "Breda",
195
+ "municipality": "Breda",
196
+ "state": "North Brabant",
197
+ "ISO3166-2-lvl4": "NL-NB",
198
+ "country": "Netherlands",
199
+ "postcode": "4834 HC",
200
+ "country_code": "nl",
201
+ },
202
+ },
203
+ "Checkbox1": True,
204
+ "Currency1": 1.23,
205
+ "DataMap1": {"background": "#cccccc", "font-size": "1.25rem"},
206
+ "DataTables1": {
207
+ "data": [
208
+ {"id": "Bob", "age": 49, "present": "Yes"},
209
+ {"id": "Sarah", "age": 47, "present": "No"},
210
+ ],
211
+ "dtOptions": {
212
+ "columns": [
213
+ {"data": "id", "title": "Name"},
214
+ {"data": "age", "title": "Age"},
215
+ {"data": "present", "title": "Present"},
216
+ ]
217
+ },
218
+ "dtFunctions": {"columns": []},
219
+ "editorMode": {},
220
+ "editorOptions": {},
221
+ "tableId": "this-table-is-unique",
222
+ },
223
+ "DateTime1": "2023-04-26 14:52:00Z",
224
+ "Day1": "04/04/2023",
225
+ "EditGrid1": [{"eg1": "Info", "eg2": "info@monkeyproofsolutions.nl"}],
226
+ "Email1": "info@simiansuite.com",
227
+ "Hidden1": '<h3 class="display-3">Content (static HTML)</h3>',
228
+ "Html1": '<h3 class="display-3">Custom HTML</h3>',
229
+ "HtmlTable1": """<table class="table">
230
+ <thead>
231
+ <tr><th scope="col">Name</th><th scope="col">Age</th><th scope="col">Present</th></tr>
232
+ </thead>
233
+ <tbody>
234
+ <tr><td>Bob</td><td>49</td><td>Yes</td></tr>
235
+ <tr><td>Sarah</td><td>47</td><td>No</td></tr>
236
+ </tbody>
237
+ </table>""",
238
+ "ImageGrid1": [
239
+ {"src": utils.encodeImage(Path(__file__).parent / "simian-logo-icon-circle.svg")},
240
+ {"src": utils.encodeImage(Path(__file__).parent / "simian-logo-icon-circle.svg")},
241
+ {"src": utils.encodeImage(Path(__file__).parent / "simian-logo-icon-circle.svg")},
242
+ {"src": utils.encodeImage(Path(__file__).parent / "simian-logo-icon-circle.svg")},
243
+ ],
244
+ "Number1": 12345,
245
+ "Password1": "y0uCaNn0tSe3m3",
246
+ "Phonenumber1": "(123) 456-7890",
247
+ "Plotly1": _plotly_default_value(),
248
+ "ResultFile1": _resultfile_default_value(),
249
+ "Tags1": ["bug", "feature", "enhancement"],
250
+ "TextArea1": """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
251
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
252
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
253
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.""",
254
+ "TextField1": "Lorem ipsum",
255
+ "Time1": "15:13",
256
+ }
257
+
258
+
259
+ def _get_doc(label: str):
260
+ return f"https://doc.simiansuite.com/simian-gui/v2.0/initialization/{label.lower()}.html"
261
+
262
+
263
+ def _get_options(component_key: str):
264
+ return _get_default_options().get(component_key)
265
+
266
+
267
+ def _get_default_options():
268
+ return {
269
+ "Address1": {
270
+ "provider": "nominatim",
271
+ "providerOptions": {"params": {}},
272
+ },
273
+ "Content1": {"html": '<span class="lead">Static HTML content</span>'},
274
+ "DataMap1": {
275
+ "valueComponent": {
276
+ "type": "textfield",
277
+ "key": "value",
278
+ "label": "Value",
279
+ "input": True,
280
+ "hideLabel": True,
281
+ "tableView": True,
282
+ },
283
+ },
284
+ "FieldSet1": {"legend": "FieldSet"},
285
+ "HtmlElement1": {"tag": "h3", "content": "Static HTML element"},
286
+ "Panel1": {"collapsible": True},
287
+ "PhoneNumber1": {
288
+ "applyMaskOn": "change",
289
+ },
290
+ "Radio1": {
291
+ "values": [
292
+ {"label": "A", "value": "a"},
293
+ {"label": "B", "value": "b"},
294
+ {"label": "C", "value": "c"},
295
+ ]
296
+ },
297
+ "Select1": {
298
+ "dataSrc": "values",
299
+ "data": {
300
+ "values": [
301
+ {"label": "A", "value": "a"},
302
+ {"label": "B", "value": "b"},
303
+ {"label": "C", "value": "c"},
304
+ ]
305
+ },
306
+ },
307
+ "Selectboxes1": {
308
+ "values": [
309
+ {"label": "A", "value": "a"},
310
+ {"label": "B", "value": "b"},
311
+ {"label": "C", "value": "c"},
312
+ ]
313
+ },
314
+ "Survey1": {
315
+ "questions": [
316
+ {
317
+ "label": "How would you rate this question on a scale of 1 to 5?",
318
+ "value": "score",
319
+ },
320
+ {"label": "And this one?", "value": "thisOne"},
321
+ ],
322
+ "values": [
323
+ {"label": "1", "value": "a"},
324
+ {"label": "2", "value": "b"},
325
+ {"label": "3", "value": "c"},
326
+ {"label": "4", "value": "d"},
327
+ {"label": "5", "value": "e"},
328
+ ],
329
+ },
330
+ }
331
+
332
+
333
+ def _add_subcomponents(component_key):
334
+ return _get_default_comps().get(component_key, [])
335
+
336
+
337
+ def _get_default_comps():
338
+ return {
339
+ "DataGrid1": [
340
+ ["dg1", "textfield", 2, None, None, "First", None],
341
+ ["dg2", "textfield", 2, None, None, "Second", None],
342
+ ],
343
+ "EditGrid1": [
344
+ ["eg1", "textfield", 2, None, None, "Name", None],
345
+ ["eg2", "email", 2, None, None, "Email", None],
346
+ ],
347
+ "FieldSet1": [
348
+ ["fs1", "textfield", 2, None, None, "Name", None],
349
+ ["fs2", "email", 2, None, None, "Email", None],
350
+ ],
351
+ "Panel1": [
352
+ ["pan1", "textfield", 2, None, None, "Name", None],
353
+ ["pan2", "email", 2, None, None, "Email", None],
354
+ ],
355
+ "Well1": [
356
+ ["w1", "textfield", 2, None, None, "Name", None],
357
+ ["w2", "email", 2, None, None, "Email", None],
358
+ ],
359
+ }
360
+
361
+
362
+ def _plotly_default_value():
363
+ return {
364
+ "data": [
365
+ {
366
+ "x": [-3, -2, -1, 0, 1, 2, 3],
367
+ "y": [-3, -2, -1, 0, 1, 2, 3],
368
+ "z": [
369
+ [6.6712802967174421e-5, 0.00337797214955247, -0.029870801373274684, -0.24495404057434964, -0.10995938332787396, -0.004314432616985781, -5.8641878725895287e-6],
370
+ [0.00074734337895483336, 0.046835385992884435, -0.59212842982359237, -4.7596121032136383, -2.1023512845906334, -0.061639793654092154, 0.00041822002330767167],
371
+ [-0.0087618924917887177, -0.13005295300439818, 1.8558917154077983, -0.72390617279329428, -0.27291654880625382, 0.49963628529592258, 0.013012486008918911],
372
+ [-0.03650620461319553, -1.3326904669589708, -1.6523454638655195, 0.98101184312384626, 2.9369303164086271, 1.4121612599396918, 0.033124949924308318],
373
+ [-0.01366906868116455, -0.48075877206514389, 0.22889945007177018, 3.6886295673017551, 2.4337891159260003, 0.58045469649513681, 0.012466690908012225],
374
+ [1.5488609851181312e-5, 0.079667927769172892, 2.0966790499089041, 5.8591286914741687, 2.2099347948240657, 0.13284922819447997, 0.0013202144463826647],
375
+ [3.2235359612692725e-5, 0.005305737765260379, 0.10991799007590233, 0.29987102822623468, 0.11068427531780239, 0.0056643866006954747, 4.1029727458267584e-5],
376
+ ],
377
+ "type": "contour",
378
+ "contours": {"coloring": "lines", "showlabels": True},
379
+ "line": {"width": 0.5, "dash": "solid"},
380
+ "colorscale": [
381
+ [0, "#3E26A8FF"],
382
+ [0.2, "#4367FDFF"],
383
+ [0.4, "#1CAADFFF"],
384
+ [0.8, "#EABA30FF"],
385
+ [1, "#F9FB15FF"],
386
+ ],
387
+ "showscale": False,
388
+ }
389
+ ],
390
+ "layout": {},
391
+ "config": {"displaylogo": False},
392
+ "styles": {
393
+ "-": "solid",
394
+ "--": "dash",
395
+ "-.": "dashdot",
396
+ ":": "dot",
397
+ "none": "solid",
398
+ },
399
+ } # fmt: skip
400
+
401
+
402
+ def _resultfile_default_value():
403
+ file = str(Path(__file__).parent / "logo.png")
404
+ url, fileName, fileSize = component._base64_encode(file, "image/png")
405
+
406
+ value = component.ResultFile.create_content([url], [fileName], [fileSize])
407
+
408
+ return value