revisit 0.0.6__py2.py3-none-any.whl → 0.0.7__py2.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.
revisit/revisit.py
CHANGED
@@ -7,6 +7,10 @@ from enum import Enum
|
|
7
7
|
import csv
|
8
8
|
from dataclasses import make_dataclass
|
9
9
|
import re
|
10
|
+
import os
|
11
|
+
import shutil
|
12
|
+
from . import widget as _widget
|
13
|
+
|
10
14
|
|
11
15
|
__all__ = [
|
12
16
|
"component",
|
@@ -15,7 +19,8 @@ __all__ = [
|
|
15
19
|
"uiConfig",
|
16
20
|
"studyMetadata",
|
17
21
|
"studyConfig",
|
18
|
-
"data"
|
22
|
+
"data",
|
23
|
+
"widget"
|
19
24
|
]
|
20
25
|
|
21
26
|
|
@@ -115,13 +120,24 @@ class _WrappedComponentBlock(_JSONableBaseModel):
|
|
115
120
|
|
116
121
|
def __add__(self, other):
|
117
122
|
"""Allows addition operator to append to sequence components list."""
|
118
|
-
if isinstance(other,
|
123
|
+
if isinstance(other, _WrappedComponent):
|
119
124
|
self.component_objects__.append(other)
|
120
125
|
self.root.components.append(other.component_name__)
|
121
126
|
return self
|
127
|
+
elif isinstance(other, _WrappedComponentBlock):
|
128
|
+
# Extend existing list of components with new set of components for tracking
|
129
|
+
self.component_objects__.extend(other.component_objects__)
|
130
|
+
|
131
|
+
# Add root object to components
|
132
|
+
self.root.components.append(other.root)
|
133
|
+
return self
|
122
134
|
return NotImplemented
|
123
135
|
|
124
|
-
def from_data(self, data_list
|
136
|
+
def from_data(self, data_list) -> DataIterator:
|
137
|
+
if not isinstance(data_list, list):
|
138
|
+
raise RevisitError(
|
139
|
+
message="'from_data' must take in a list of data rows. Use reVISit's 'data' method to parse a CSV file into a valid input."
|
140
|
+
)
|
125
141
|
return DataIterator(data_list, self)
|
126
142
|
|
127
143
|
|
@@ -366,6 +382,67 @@ def data(file_path: str) -> List[Any]:
|
|
366
382
|
return data_rows
|
367
383
|
|
368
384
|
|
385
|
+
def widget(study: _WrappedStudyConfig, revisitPath: str):
|
386
|
+
if not os.path.isdir(revisitPath):
|
387
|
+
raise RevisitError(message=f'"{revisitPath}" does not exist.')
|
388
|
+
|
389
|
+
extracted_paths = []
|
390
|
+
|
391
|
+
for component in study.root.components.values():
|
392
|
+
if hasattr(component.root, 'path'):
|
393
|
+
|
394
|
+
fileName = component.root.path.split('/')[-1]
|
395
|
+
|
396
|
+
if component.root.type == 'react-component':
|
397
|
+
dest = f"{revisitPath}/src/public/__revisit-widget/assets/{fileName}"
|
398
|
+
else:
|
399
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
400
|
+
|
401
|
+
extracted_paths.append({
|
402
|
+
"src": component.root.path,
|
403
|
+
"dest": dest
|
404
|
+
})
|
405
|
+
|
406
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
407
|
+
component.root.path = newPath
|
408
|
+
|
409
|
+
uiConfig = study.root.uiConfig
|
410
|
+
if uiConfig.helpTextPath is not None:
|
411
|
+
|
412
|
+
fileName = uiConfig.helpTextPath.split('/')[-1]
|
413
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
414
|
+
|
415
|
+
extracted_paths.append({
|
416
|
+
"src": uiConfig.helpTextPath,
|
417
|
+
"dest": dest
|
418
|
+
})
|
419
|
+
|
420
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
421
|
+
uiConfig.helpTextPath = newPath
|
422
|
+
|
423
|
+
if uiConfig.logoPath is not None:
|
424
|
+
|
425
|
+
fileName = uiConfig.logoPath.split('/')[-1]
|
426
|
+
|
427
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
428
|
+
|
429
|
+
extracted_paths.append({
|
430
|
+
"src": uiConfig.logoPath,
|
431
|
+
"dest": dest
|
432
|
+
})
|
433
|
+
|
434
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
435
|
+
uiConfig.logoPath = newPath
|
436
|
+
|
437
|
+
# Copy all files
|
438
|
+
for item in extracted_paths:
|
439
|
+
_copy_file(item['src'], item['dest'])
|
440
|
+
|
441
|
+
w = _widget.Widget()
|
442
|
+
w.config = json.loads(study.__str__())
|
443
|
+
return w
|
444
|
+
|
445
|
+
|
369
446
|
# ------- PRIVATE FUNCTIONS ------------ #
|
370
447
|
|
371
448
|
def _validate_component(kwargs: dict):
|
@@ -496,7 +573,7 @@ def pretty_error(errors):
|
|
496
573
|
|
497
574
|
def _get_filtered_kwargs(class_type: Any, kwargs):
|
498
575
|
try:
|
499
|
-
possible_items = get_args(class_type.
|
576
|
+
possible_items = get_args(class_type.model_fields.get('root').annotation)
|
500
577
|
except AttributeError:
|
501
578
|
possible_items = [class_type]
|
502
579
|
|
@@ -529,3 +606,14 @@ def _extract_datum_value(text: str) -> str:
|
|
529
606
|
if match:
|
530
607
|
return match.group(1) # Return the captured part (i.e., 'thing')
|
531
608
|
return None # Return None if the pattern doesn't match
|
609
|
+
|
610
|
+
|
611
|
+
def _copy_file(src: str, dest: str):
|
612
|
+
# Check if file exists
|
613
|
+
if not os.path.exists(src):
|
614
|
+
raise RevisitError(message=f'File "{src}" not found.')
|
615
|
+
|
616
|
+
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
617
|
+
|
618
|
+
print(f'Copying file from {src} to {dest}')
|
619
|
+
shutil.copyfile(src, dest)
|
revisit/widget.py
CHANGED
@@ -47,3 +47,7 @@ class Widget(anywidget.AnyWidget):
|
|
47
47
|
self.internalWidget.value += 1
|
48
48
|
# internalWidget.value += 1
|
49
49
|
# print("{name} changed from {old} to {new}".format(**change))
|
50
|
+
|
51
|
+
# def set(self, study: rvt._WrappedStudyConfig):
|
52
|
+
# self.config = json.loads(study.__str__())
|
53
|
+
# return self
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: revisit
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.7
|
4
4
|
Requires-Dist: anywidget
|
5
5
|
Requires-Dist: ipykernel>=6.29.5
|
6
6
|
Requires-Dist: pydantic>=2.10.5
|
@@ -58,3 +58,17 @@ yarn run dev
|
|
58
58
|
Open `example.ipynb` in JupyterLab, VS Code, or your favorite editor
|
59
59
|
to start developing. Changes made in `js/` will be reflected
|
60
60
|
in the notebook.
|
61
|
+
|
62
|
+
|
63
|
+
## CODE GEN
|
64
|
+
|
65
|
+
```bash
|
66
|
+
datamodel-codegen --input StudyConfigSchema.json --output models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports typing.TypedDict --input-file-type jsonschema --special-field-name-prefix we_are_going_to_replace_this && sed -i '' 's/we_are_going_to_replace_this_//g' src/revisit/models.py
|
67
|
+
```
|
68
|
+
|
69
|
+
## TESTS
|
70
|
+
|
71
|
+
```bash
|
72
|
+
cd revisit-py
|
73
|
+
python -m unittest tests.test_module_one
|
74
|
+
```
|
@@ -1,9 +1,9 @@
|
|
1
1
|
revisit/__init__.py,sha256=QCvYt8m9QwpjcK4dv6GlLMUDCzRXGy16cua1r2biNCg,255
|
2
2
|
revisit/models.py,sha256=c-Hsd6XqeIP-hybH6MUovHG65XXueRhaMEVJZW1ViX0,120701
|
3
|
-
revisit/revisit.py,sha256=
|
4
|
-
revisit/widget.py,sha256=
|
3
|
+
revisit/revisit.py,sha256=yYDzdaOw8t8bqNnhwbPhy8eRO62tHa6H4FGRECnPGXA,22001
|
4
|
+
revisit/widget.py,sha256=qx1xehXLLYlSdR44lDJ_nnb5czljsvGFBZNEV79G77I,1850
|
5
5
|
revisit/static/widget.css,sha256=TLu5F6k0CvowQtmApPswG-JZUXYszo7a10dVWKnZsIg,647
|
6
6
|
revisit/static/widget.js,sha256=MlZ2jHlh_ADsUKMC5nZaSAmW73-4y2B57NcS3E5Jh3Q,187153
|
7
|
-
revisit-0.0.
|
8
|
-
revisit-0.0.
|
9
|
-
revisit-0.0.
|
7
|
+
revisit-0.0.7.dist-info/METADATA,sha256=8SdNZppKm4OeGvuBWOvXOcfx26SG8r4sDIeCkD70YvY,1712
|
8
|
+
revisit-0.0.7.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
9
|
+
revisit-0.0.7.dist-info/RECORD,,
|
File without changes
|