revisit 0.0.11__py2.py3-none-any.whl → 0.0.13__py2.py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- revisit/StudyConfigSchema.json +2130 -0
- revisit/revisit.py +108 -6
- revisit/static/widget.css +0 -1
- revisit/static/widget.js +5 -6
- revisit/widget.py +9 -35
- revisit-0.0.13.dist-info/METADATA +291 -0
- revisit-0.0.13.dist-info/RECORD +10 -0
- revisit-0.0.11.dist-info/METADATA +0 -74
- revisit-0.0.11.dist-info/RECORD +0 -9
- {revisit-0.0.11.dist-info → revisit-0.0.13.dist-info}/WHEEL +0 -0
revisit/widget.py
CHANGED
@@ -2,6 +2,7 @@ import importlib.metadata
|
|
2
2
|
import pathlib
|
3
3
|
import anywidget # type: ignore
|
4
4
|
import traitlets # type: ignore
|
5
|
+
import pandas as pd
|
5
6
|
|
6
7
|
try:
|
7
8
|
__version__ = importlib.metadata.version("revisit_notebook_widget")
|
@@ -9,45 +10,18 @@ except importlib.metadata.PackageNotFoundError:
|
|
9
10
|
__version__ = "unknown"
|
10
11
|
|
11
12
|
|
12
|
-
# class Widget2(anywidget.AnyWidget):
|
13
|
-
class TestWidget(anywidget.AnyWidget):
|
14
|
-
_esm = """
|
15
|
-
function render({ model, el }) {
|
16
|
-
let button = document.createElement("button");
|
17
|
-
button.innerHTML = `count is ${model.get("value")}`;
|
18
|
-
button.addEventListener("click", () => {
|
19
|
-
model.set("value", model.get("value") + 1);
|
20
|
-
model.save_changes();
|
21
|
-
});
|
22
|
-
model.on("change:value", () => {
|
23
|
-
button.innerHTML = `count is ${model.get("value")}`;
|
24
|
-
});
|
25
|
-
el.classList.add("counter-widget");
|
26
|
-
el.appendChild(button);
|
27
|
-
}
|
28
|
-
export default { render };
|
29
|
-
"""
|
30
|
-
_css = """
|
31
|
-
.counter-widget button { color: white; font-size: 1.75rem; background-color: #ea580c; padding: 0.5rem 1rem; border: none; border-radius: 0.25rem; }
|
32
|
-
.counter-widget button:hover { background-color: #9a3412; }
|
33
|
-
"""
|
34
|
-
value = traitlets.Int(0).tag(sync=True)
|
35
|
-
|
36
|
-
|
37
13
|
class Widget(anywidget.AnyWidget):
|
38
14
|
_esm = pathlib.Path(__file__).parent / "static" / "widget.js"
|
39
15
|
_css = pathlib.Path(__file__).parent / "static" / "widget.css"
|
40
|
-
# value = traitlets.Int(0).tag(sync=True)
|
41
16
|
config = traitlets.Dict({}).tag(sync=True)
|
42
17
|
sequence = traitlets.List([]).tag(sync=True)
|
43
|
-
|
18
|
+
participants_data_json = traitlets.List([]).tag(sync=True)
|
19
|
+
participants_data_tidy = traitlets.Dict({}).tag(sync=True)
|
44
20
|
|
45
|
-
|
46
|
-
|
47
|
-
self.
|
48
|
-
|
49
|
-
# print("{name} changed from {old} to {new}".format(**change))
|
21
|
+
def get_df(self):
|
22
|
+
# Extract rows and headers
|
23
|
+
rows = self.participants_data_tidy['rows']
|
24
|
+
header = self.participants_data_tidy['header']
|
50
25
|
|
51
|
-
|
52
|
-
|
53
|
-
# return self
|
26
|
+
# Create DataFrame
|
27
|
+
return pd.DataFrame(rows, columns=header)
|
@@ -0,0 +1,291 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: revisit
|
3
|
+
Version: 0.0.13
|
4
|
+
Requires-Dist: altair[all]>=5.5.0
|
5
|
+
Requires-Dist: anywidget
|
6
|
+
Requires-Dist: ipykernel>=6.29.5
|
7
|
+
Requires-Dist: pandas>=2.2.3
|
8
|
+
Requires-Dist: pydantic>=2.10.5
|
9
|
+
Provides-Extra: dev
|
10
|
+
Requires-Dist: jupyterlab; extra == 'dev'
|
11
|
+
Requires-Dist: watchfiles; extra == 'dev'
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
|
14
|
+
# revisit
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
```sh
|
19
|
+
pip install revisit
|
20
|
+
```
|
21
|
+
|
22
|
+
or with [uv](https://github.com/astral-sh/uv):
|
23
|
+
|
24
|
+
```sh
|
25
|
+
uv add revisit
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
The reVISit python package wraps the standard items of the reVISit configuration file with readable, easy-to-use functions. We expose a factory function for each top-level item in the reVISit configuration: `studyMetadata`, `uiConfig`, `components`, `sequence`, and `studyMetadata`. Currently, we do not expose a `baseComponents` function. Instead, base components are still well-defined components and can be passed during the creation of another component. The final configuration will not include base components but will have the expected inherited output.
|
31
|
+
|
32
|
+
Each factory function takes in the same parameters as the reVISit configuration file. For example, the `studyMetadata` function requires the author, organizations, title, version, and description parameters. Robust error output will help you, the user, understand what is required in each function. For the sake of brevity, we do not list every possible parameter since these are already defined in the current study configuration. Instead, we will show additional required/optional parameters as well as additional methods and other exposed functions.
|
33
|
+
|
34
|
+
### Functions
|
35
|
+
|
36
|
+
#### `component(component_name__: str, base__: Optional[component], **kwargs: dict) -> Component`
|
37
|
+
|
38
|
+
**Description**:
|
39
|
+
|
40
|
+
Instantiates a Component class with the given input parameters.
|
41
|
+
|
42
|
+
#### **Parameters**:
|
43
|
+
| Parameter | Type | Description | Default Value |
|
44
|
+
|-----------|--------|---------------------------------|---------------|
|
45
|
+
| `component_name__` | `str` | Names the component for use in the final configuration file. | _None_ |
|
46
|
+
| `base__` | `Optional[component]` | When a base component is passed, all properties of the base are inherited by the component. Any other specified property during input will override base properties. | _None_ |
|
47
|
+
| `**kwargs` | `dict` | The component function requires any property that the component already requires, such as "type". Refer to the configuration documentation for required properties. | _None_ |
|
48
|
+
|
49
|
+
#### **Returns**:
|
50
|
+
- `Component`: Returns an instantiation of the Component class.
|
51
|
+
|
52
|
+
#### **Raises**:
|
53
|
+
- `RevisitError`: If the required properties are not specified, and exception will be raised.
|
54
|
+
|
55
|
+
#### **Example**:
|
56
|
+
```python
|
57
|
+
import revisit as rvt
|
58
|
+
|
59
|
+
# Initializing a markdown component with an empty response list.
|
60
|
+
my_component = rvt.component(
|
61
|
+
component_name__='my-component',
|
62
|
+
response=[],
|
63
|
+
type='markdown',
|
64
|
+
path='./assets/my-markdown-file.md'
|
65
|
+
)
|
66
|
+
|
67
|
+
# Instantiating a component with the base as "my_component".
|
68
|
+
my_other_component = rvt.component(
|
69
|
+
component_name__='my-other-component',
|
70
|
+
base__=my_component,
|
71
|
+
path='./assets/my-other-markdown-file.md'
|
72
|
+
)
|
73
|
+
```
|
74
|
+
|
75
|
+
|
76
|
+
#### `response(**kwargs: dict) -> Response`
|
77
|
+
|
78
|
+
**Description**:
|
79
|
+
|
80
|
+
Instantiates a Response class with the given input parameters.
|
81
|
+
|
82
|
+
#### **Parameters**:
|
83
|
+
| Parameter | Type | Description | Default Value |
|
84
|
+
|-----------|--------|---------------------------------|---------------|
|
85
|
+
| `**kwargs` | `dict` | The component function requires any property that the component already requires, such as "type". Refer to the configuration documentation for required properties. | _None_ |
|
86
|
+
|
87
|
+
#### **Returns**:
|
88
|
+
- `Response`: Returns an instantiation of the Response class.
|
89
|
+
|
90
|
+
#### **Raises**:
|
91
|
+
- `RevisitError`: If the required properties are not specified, and exception will be raised.
|
92
|
+
|
93
|
+
#### **Example**:
|
94
|
+
```python
|
95
|
+
import revisit as rvt
|
96
|
+
|
97
|
+
# Initializing a matrix radio response
|
98
|
+
my_response = rvt.response(
|
99
|
+
type='matrix-radio',
|
100
|
+
answerOptions='likely5',
|
101
|
+
questionOptions=['Question 1', 'Question 2', 'Question 3'],
|
102
|
+
required=True,
|
103
|
+
location='sidebar'
|
104
|
+
)
|
105
|
+
```
|
106
|
+
|
107
|
+
### Classes
|
108
|
+
|
109
|
+
#### `Component`
|
110
|
+
|
111
|
+
**Description**:
|
112
|
+
A brief summary of the class's purpose and functionality.
|
113
|
+
|
114
|
+
#### **Attributes**:
|
115
|
+
| Attribute | Type | Description | Default Value |
|
116
|
+
|-------------|----------|-------------------------------------|---------------|
|
117
|
+
| `component_name__` | `type` | Description of attribute 1. | `default` |
|
118
|
+
| `base__` | `type` | Description of attribute 2. | _None_ |
|
119
|
+
|
120
|
+
|
121
|
+
#### **Methods**:
|
122
|
+
##### `responses(responses: List[Response]) -> self`
|
123
|
+
|
124
|
+
**Description**:
|
125
|
+
Sets responses for the component
|
126
|
+
|
127
|
+
**Parameters**:
|
128
|
+
| Parameter | Type | Description | Default Value |
|
129
|
+
|-------------|----------|-------------------------------------|---------------|
|
130
|
+
| `responses` | `List[Response]` | Valid list of responses. | _None_ |
|
131
|
+
|
132
|
+
**Returns**:
|
133
|
+
- `self`: Returns self for method chaining.
|
134
|
+
|
135
|
+
**Raises**:
|
136
|
+
- `RevisitError`: If the list is not a valid list of responses, raises and exception.
|
137
|
+
|
138
|
+
#### **Example**:
|
139
|
+
```python
|
140
|
+
my_response=rvt.response(
|
141
|
+
id='my_response',
|
142
|
+
type='dropdown',
|
143
|
+
options=['Option 1', 'Option 2']
|
144
|
+
)
|
145
|
+
|
146
|
+
my_component = rvt.component(
|
147
|
+
component_name__='my_component',
|
148
|
+
type='markdown',
|
149
|
+
path='assets/my-markdown-file.md'
|
150
|
+
).responses([
|
151
|
+
my_response
|
152
|
+
])
|
153
|
+
```
|
154
|
+
|
155
|
+
#### `get_response(id: str) -> Response | None`
|
156
|
+
|
157
|
+
**Description**:
|
158
|
+
Returns the response of the component with the given ID. If the Response does not exist, returns `None`.
|
159
|
+
|
160
|
+
**Parameters**:
|
161
|
+
| Parameter | Type | Description | Default Value |
|
162
|
+
|-------------|----------|-------------------------------------|---------------|
|
163
|
+
| `id` | `str` | ID of Response | _None_ |
|
164
|
+
|
165
|
+
**Returns**:
|
166
|
+
- `Response`: The response with the given ID.
|
167
|
+
|
168
|
+
#### **Examples**:
|
169
|
+
```python
|
170
|
+
the_response = my_component.get_response(id='the_response')
|
171
|
+
|
172
|
+
if the_response is not None:
|
173
|
+
print(the_response)
|
174
|
+
```
|
175
|
+
|
176
|
+
#### `edit_response(id: str, **kwargs: dict) -> self`
|
177
|
+
|
178
|
+
**Description**:
|
179
|
+
Edits the Response in the Component with the given ID. This is done by creating a new copy of the existing Response.
|
180
|
+
|
181
|
+
**Parameters**:
|
182
|
+
| Parameter | Type | Description | Default Value |
|
183
|
+
|-------------|----------|-------------------------------------|---------------|
|
184
|
+
| `id` | `str` | ID of Response | _None_ |
|
185
|
+
|
186
|
+
**Returns**:
|
187
|
+
- `self`: Returns self for method chaining.
|
188
|
+
|
189
|
+
#### **Examples**:
|
190
|
+
```python
|
191
|
+
test_response = rvt.response(
|
192
|
+
id='test_response',
|
193
|
+
type='shortText',
|
194
|
+
prompt='Original Prompt:',
|
195
|
+
required=True
|
196
|
+
)
|
197
|
+
|
198
|
+
component_one = rvt.component(
|
199
|
+
component_name__='component_one',
|
200
|
+
type='questionnaire',
|
201
|
+
response=[test_response]
|
202
|
+
)
|
203
|
+
|
204
|
+
component_two = rvt.component(
|
205
|
+
component_name__='component_two',
|
206
|
+
type='questionnaire',
|
207
|
+
response=[test_response]
|
208
|
+
).edit_response(id='test_response', prompt='New Prompt', required=False)
|
209
|
+
|
210
|
+
print(component_one)
|
211
|
+
'''
|
212
|
+
Expected Output:
|
213
|
+
{
|
214
|
+
"response": [
|
215
|
+
{
|
216
|
+
"id": "test_response",
|
217
|
+
"prompt": "Original Prompt:",
|
218
|
+
"required": true,
|
219
|
+
"type": "shortText"
|
220
|
+
}
|
221
|
+
],
|
222
|
+
"type": "questionnaire"
|
223
|
+
}
|
224
|
+
'''
|
225
|
+
print(component_two)
|
226
|
+
'''
|
227
|
+
{
|
228
|
+
"response": [
|
229
|
+
{
|
230
|
+
"id": "test_response",
|
231
|
+
"prompt": "New Prompt",
|
232
|
+
"required": false,
|
233
|
+
"type": "shortText"
|
234
|
+
}
|
235
|
+
],
|
236
|
+
"type": "questionnaire"
|
237
|
+
}
|
238
|
+
'''
|
239
|
+
```
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
## Development
|
244
|
+
|
245
|
+
We recommend using [uv](https://github.com/astral-sh/uv) for development.
|
246
|
+
It will automatically manage virtual environments and dependencies for you.
|
247
|
+
|
248
|
+
```sh
|
249
|
+
uv run jupyter lab example.ipynb
|
250
|
+
```
|
251
|
+
|
252
|
+
Alternatively, create and manage your own virtual environment:
|
253
|
+
|
254
|
+
```sh
|
255
|
+
python -m venv .venv
|
256
|
+
source .venv/bin/activate
|
257
|
+
pip install -e ".[dev]"
|
258
|
+
jupyter lab example.ipynb
|
259
|
+
```
|
260
|
+
|
261
|
+
The widget front-end code bundles it's JavaScript dependencies. After setting up Python,
|
262
|
+
make sure to install these dependencies locally:
|
263
|
+
|
264
|
+
```sh
|
265
|
+
yarn install
|
266
|
+
```
|
267
|
+
|
268
|
+
While developing, you can run the following in a separate terminal to automatically
|
269
|
+
rebuild JavaScript as you make changes:
|
270
|
+
|
271
|
+
```sh
|
272
|
+
yarn run dev
|
273
|
+
```
|
274
|
+
|
275
|
+
Open `example.ipynb` in JupyterLab, VS Code, or your favorite editor
|
276
|
+
to start developing. Changes made in `js/` will be reflected
|
277
|
+
in the notebook.
|
278
|
+
|
279
|
+
|
280
|
+
## CODE GEN
|
281
|
+
|
282
|
+
```bash
|
283
|
+
datamodel-codegen --input src/revisit/StudyConfigSchema.json --output src/revisit/models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports "typing.TypedDict, warnings" --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
|
284
|
+
```
|
285
|
+
|
286
|
+
## TESTS
|
287
|
+
|
288
|
+
```bash
|
289
|
+
cd revisit-py
|
290
|
+
python -m unittest tests.test_module_one
|
291
|
+
```
|
@@ -0,0 +1,10 @@
|
|
1
|
+
revisit/StudyConfigSchema.json,sha256=xtzwZifuPJoiHASx0o8PHqBuh5L30mjBlhQ5eqsYm10,132168
|
2
|
+
revisit/__init__.py,sha256=QCvYt8m9QwpjcK4dv6GlLMUDCzRXGy16cua1r2biNCg,255
|
3
|
+
revisit/models.py,sha256=FRy8IlUAtDS3gdmZwwvqR935lbViTPnnr7k0CAkDkzI,134084
|
4
|
+
revisit/revisit.py,sha256=ZJDKbaQqvMTatcBxO8l7LhQ-EBb-2A_RKinQTIJe58k,26864
|
5
|
+
revisit/widget.py,sha256=VvFqRvvvn86fW8ASe1pxaAvh5ZLvvSRThI5XtlCdgcg,915
|
6
|
+
revisit/static/widget.css,sha256=TLu5F6k0CvowQtmApPswG-JZUXYszo7a10dVWKnZsIg,647
|
7
|
+
revisit/static/widget.js,sha256=G5J9A5HvuMEEPKz2hAUGG25jFz4KHemocGLnJgwF_b8,186472
|
8
|
+
revisit-0.0.13.dist-info/METADATA,sha256=SoINQTeJwTFfaKiW2mpn9KhNXC4DT8Ew6lk3AWU59aM,8914
|
9
|
+
revisit-0.0.13.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
10
|
+
revisit-0.0.13.dist-info/RECORD,,
|
@@ -1,74 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: revisit
|
3
|
-
Version: 0.0.11
|
4
|
-
Requires-Dist: anywidget
|
5
|
-
Requires-Dist: ipykernel>=6.29.5
|
6
|
-
Requires-Dist: pydantic>=2.10.5
|
7
|
-
Provides-Extra: dev
|
8
|
-
Requires-Dist: jupyterlab; extra == 'dev'
|
9
|
-
Requires-Dist: watchfiles; extra == 'dev'
|
10
|
-
Description-Content-Type: text/markdown
|
11
|
-
|
12
|
-
# revisit
|
13
|
-
|
14
|
-
## Installation
|
15
|
-
|
16
|
-
```sh
|
17
|
-
pip install revisit
|
18
|
-
```
|
19
|
-
|
20
|
-
or with [uv](https://github.com/astral-sh/uv):
|
21
|
-
|
22
|
-
```sh
|
23
|
-
uv add revisit
|
24
|
-
```
|
25
|
-
|
26
|
-
## Development
|
27
|
-
|
28
|
-
We recommend using [uv](https://github.com/astral-sh/uv) for development.
|
29
|
-
It will automatically manage virtual environments and dependencies for you.
|
30
|
-
|
31
|
-
```sh
|
32
|
-
uv run jupyter lab example.ipynb
|
33
|
-
```
|
34
|
-
|
35
|
-
Alternatively, create and manage your own virtual environment:
|
36
|
-
|
37
|
-
```sh
|
38
|
-
python -m venv .venv
|
39
|
-
source .venv/bin/activate
|
40
|
-
pip install -e ".[dev]"
|
41
|
-
jupyter lab example.ipynb
|
42
|
-
```
|
43
|
-
|
44
|
-
The widget front-end code bundles it's JavaScript dependencies. After setting up Python,
|
45
|
-
make sure to install these dependencies locally:
|
46
|
-
|
47
|
-
```sh
|
48
|
-
yarn install
|
49
|
-
```
|
50
|
-
|
51
|
-
While developing, you can run the following in a separate terminal to automatically
|
52
|
-
rebuild JavaScript as you make changes:
|
53
|
-
|
54
|
-
```sh
|
55
|
-
yarn run dev
|
56
|
-
```
|
57
|
-
|
58
|
-
Open `example.ipynb` in JupyterLab, VS Code, or your favorite editor
|
59
|
-
to start developing. Changes made in `js/` will be reflected
|
60
|
-
in the notebook.
|
61
|
-
|
62
|
-
|
63
|
-
## CODE GEN
|
64
|
-
|
65
|
-
```bash
|
66
|
-
datamodel-codegen --input StudyConfigSchema.json --output src/revisit/models.py --custom-template-dir custom_templates --output-model-type pydantic_v2.BaseModel --additional-imports "typing.TypedDict, warnings" --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
|
-
```
|
revisit-0.0.11.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
revisit/__init__.py,sha256=QCvYt8m9QwpjcK4dv6GlLMUDCzRXGy16cua1r2biNCg,255
|
2
|
-
revisit/models.py,sha256=FRy8IlUAtDS3gdmZwwvqR935lbViTPnnr7k0CAkDkzI,134084
|
3
|
-
revisit/revisit.py,sha256=J-ci4HhUq-bgkiH2s2mU5qntxio_r0-behQsQ7o_pY8,23361
|
4
|
-
revisit/widget.py,sha256=qx1xehXLLYlSdR44lDJ_nnb5czljsvGFBZNEV79G77I,1850
|
5
|
-
revisit/static/widget.css,sha256=GlTPXc8vQmM78wYzPsTppy3r_zOqG7sqY1hKSmmmZNk,2769
|
6
|
-
revisit/static/widget.js,sha256=UjufNoAG0qIo5JFx95wDEuxc8MWtAAE18qG2V5f0U6M,1356847
|
7
|
-
revisit-0.0.11.dist-info/METADATA,sha256=ex90CXRxcfhry6uKNm8SIvrzY01huBojGJbcGmr1A48,1737
|
8
|
-
revisit-0.0.11.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
9
|
-
revisit-0.0.11.dist-info/RECORD,,
|
File without changes
|