revisit 0.0.6__py2.py3-none-any.whl → 0.0.7__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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, _WrappedComponentBlock) or isinstance(other, _WrappedComponent):
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: 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.__fields__.get('root').annotation)
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.6
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=U45q5nQtvfIBei6W9IaIIIWHoPP4ivZjxN4XqeR18uc,19305
4
- revisit/widget.py,sha256=ih0XhRjkih8vpeDr1SO8l8zMydZHLSXxVaFzvA8up_8,1722
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.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.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,,