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
- for response in self.root.response:
84
- if response.root.id == id:
85
- response.set(**kwargs)
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, _WrappedComponentBlock) or isinstance(other, _WrappedComponent):
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: 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.__fields__.get('root').annotation)
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.6
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=U45q5nQtvfIBei6W9IaIIIWHoPP4ivZjxN4XqeR18uc,19305
4
- revisit/widget.py,sha256=ih0XhRjkih8vpeDr1SO8l8zMydZHLSXxVaFzvA8up_8,1722
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.6.dist-info/METADATA,sha256=1dA6YZT5iS8nYMryUJMWc9LPRyUfIbDSEXFcgHzYaw4,1261
8
- revisit-0.0.6.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
9
- revisit-0.0.6.dist-info/RECORD,,
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,,