revisit 0.0.6__py2.py3-none-any.whl → 0.0.8__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
|
|
@@ -53,6 +58,9 @@ class _WrappedResponse(_JSONableBaseModel):
|
|
53
58
|
self.root = _validate_response(self.root.__dict__)
|
54
59
|
return self
|
55
60
|
|
61
|
+
def clone(self):
|
62
|
+
return response(**self.root.__dict__)
|
63
|
+
|
56
64
|
|
57
65
|
# Private
|
58
66
|
class _WrappedComponent(_JSONableBaseModel):
|
@@ -80,9 +88,20 @@ class _WrappedComponent(_JSONableBaseModel):
|
|
80
88
|
return None
|
81
89
|
|
82
90
|
def edit_response(self, id: str, **kwargs) -> _WrappedComponent:
|
83
|
-
|
84
|
-
|
85
|
-
|
91
|
+
print(self.root.response)
|
92
|
+
for r in self.root.response:
|
93
|
+
if r.root.id == id:
|
94
|
+
# Get dict
|
95
|
+
response_dict = r.root.__dict__
|
96
|
+
# Create new response
|
97
|
+
new_response = response(**response_dict)
|
98
|
+
# Set with new values
|
99
|
+
new_response.set(**kwargs)
|
100
|
+
# Filter out old response
|
101
|
+
self.root.response = [_r for _r in self.root.response if _r.root.id != id]
|
102
|
+
# Add new response
|
103
|
+
self.root.response.append(new_response)
|
104
|
+
# Return component
|
86
105
|
return self
|
87
106
|
|
88
107
|
raise ValueError('No response with given ID found.')
|
@@ -100,6 +119,9 @@ class _WrappedComponent(_JSONableBaseModel):
|
|
100
119
|
|
101
120
|
return self
|
102
121
|
|
122
|
+
def clone(self, component_name__):
|
123
|
+
return component(**self.root.__dict__, component_name__=component_name__)
|
124
|
+
|
103
125
|
|
104
126
|
class _WrappedStudyMetadata(_JSONableBaseModel):
|
105
127
|
root: rvt_models.StudyMetadata
|
@@ -115,13 +137,24 @@ class _WrappedComponentBlock(_JSONableBaseModel):
|
|
115
137
|
|
116
138
|
def __add__(self, other):
|
117
139
|
"""Allows addition operator to append to sequence components list."""
|
118
|
-
if isinstance(other,
|
140
|
+
if isinstance(other, _WrappedComponent):
|
119
141
|
self.component_objects__.append(other)
|
120
142
|
self.root.components.append(other.component_name__)
|
121
143
|
return self
|
144
|
+
elif isinstance(other, _WrappedComponentBlock):
|
145
|
+
# Extend existing list of components with new set of components for tracking
|
146
|
+
self.component_objects__.extend(other.component_objects__)
|
147
|
+
|
148
|
+
# Add root object to components
|
149
|
+
self.root.components.append(other.root)
|
150
|
+
return self
|
122
151
|
return NotImplemented
|
123
152
|
|
124
|
-
def from_data(self, data_list
|
153
|
+
def from_data(self, data_list) -> DataIterator:
|
154
|
+
if not isinstance(data_list, list):
|
155
|
+
raise RevisitError(
|
156
|
+
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."
|
157
|
+
)
|
125
158
|
return DataIterator(data_list, self)
|
126
159
|
|
127
160
|
|
@@ -366,6 +399,67 @@ def data(file_path: str) -> List[Any]:
|
|
366
399
|
return data_rows
|
367
400
|
|
368
401
|
|
402
|
+
def widget(study: _WrappedStudyConfig, revisitPath: str):
|
403
|
+
if not os.path.isdir(revisitPath):
|
404
|
+
raise RevisitError(message=f'"{revisitPath}" does not exist.')
|
405
|
+
|
406
|
+
extracted_paths = []
|
407
|
+
|
408
|
+
for component in study.root.components.values():
|
409
|
+
if hasattr(component.root, 'path'):
|
410
|
+
|
411
|
+
fileName = component.root.path.split('/')[-1]
|
412
|
+
|
413
|
+
if component.root.type == 'react-component':
|
414
|
+
dest = f"{revisitPath}/src/public/__revisit-widget/assets/{fileName}"
|
415
|
+
else:
|
416
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
417
|
+
|
418
|
+
extracted_paths.append({
|
419
|
+
"src": component.root.path,
|
420
|
+
"dest": dest
|
421
|
+
})
|
422
|
+
|
423
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
424
|
+
component.root.path = newPath
|
425
|
+
|
426
|
+
uiConfig = study.root.uiConfig
|
427
|
+
if uiConfig.helpTextPath is not None:
|
428
|
+
|
429
|
+
fileName = uiConfig.helpTextPath.split('/')[-1]
|
430
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
431
|
+
|
432
|
+
extracted_paths.append({
|
433
|
+
"src": uiConfig.helpTextPath,
|
434
|
+
"dest": dest
|
435
|
+
})
|
436
|
+
|
437
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
438
|
+
uiConfig.helpTextPath = newPath
|
439
|
+
|
440
|
+
if uiConfig.logoPath is not None:
|
441
|
+
|
442
|
+
fileName = uiConfig.logoPath.split('/')[-1]
|
443
|
+
|
444
|
+
dest = f"{revisitPath}/public/__revisit-widget/assets/{fileName}"
|
445
|
+
|
446
|
+
extracted_paths.append({
|
447
|
+
"src": uiConfig.logoPath,
|
448
|
+
"dest": dest
|
449
|
+
})
|
450
|
+
|
451
|
+
newPath = f"__revisit-widget/assets/{fileName}"
|
452
|
+
uiConfig.logoPath = newPath
|
453
|
+
|
454
|
+
# Copy all files
|
455
|
+
for item in extracted_paths:
|
456
|
+
_copy_file(item['src'], item['dest'])
|
457
|
+
|
458
|
+
w = _widget.Widget()
|
459
|
+
w.config = json.loads(study.__str__())
|
460
|
+
return w
|
461
|
+
|
462
|
+
|
369
463
|
# ------- PRIVATE FUNCTIONS ------------ #
|
370
464
|
|
371
465
|
def _validate_component(kwargs: dict):
|
@@ -496,7 +590,7 @@ def pretty_error(errors):
|
|
496
590
|
|
497
591
|
def _get_filtered_kwargs(class_type: Any, kwargs):
|
498
592
|
try:
|
499
|
-
possible_items = get_args(class_type.
|
593
|
+
possible_items = get_args(class_type.model_fields.get('root').annotation)
|
500
594
|
except AttributeError:
|
501
595
|
possible_items = [class_type]
|
502
596
|
|
@@ -529,3 +623,14 @@ def _extract_datum_value(text: str) -> str:
|
|
529
623
|
if match:
|
530
624
|
return match.group(1) # Return the captured part (i.e., 'thing')
|
531
625
|
return None # Return None if the pattern doesn't match
|
626
|
+
|
627
|
+
|
628
|
+
def _copy_file(src: str, dest: str):
|
629
|
+
# Check if file exists
|
630
|
+
if not os.path.exists(src):
|
631
|
+
raise RevisitError(message=f'File "{src}" not found.')
|
632
|
+
|
633
|
+
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
634
|
+
|
635
|
+
print(f'Copying file from {src} to {dest}')
|
636
|
+
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.8
|
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=huYhGnzG5gL2KA3Lw0dIDCI8erm82uP6k5XDcoo_Q38,22683
|
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.8.dist-info/METADATA,sha256=RShPLubx2i7A4ZKXmPy0uzGocBhkZHZmbpdDk4iobhQ,1712
|
8
|
+
revisit-0.0.8.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
9
|
+
revisit-0.0.8.dist-info/RECORD,,
|
File without changes
|