experiment_server 0.3.4__tar.gz → 0.3.6__tar.gz

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.
Files changed (25) hide show
  1. {experiment_server-0.3.4 → experiment_server-0.3.6}/PKG-INFO +132 -40
  2. {experiment_server-0.3.4 → experiment_server-0.3.6}/README.md +128 -37
  3. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/_api.py +86 -42
  4. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/_client.py +28 -0
  5. experiment_server-0.3.6/experiment_server/_participant_ordering.py +229 -0
  6. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/_process_config.py +134 -118
  7. {experiment_server-0.3.4 → experiment_server-0.3.6}/pyproject.toml +6 -8
  8. experiment_server-0.3.6/sample_config.toml +119 -0
  9. experiment_server-0.3.4/experiment_server/_participant_ordering.py +0 -126
  10. experiment_server-0.3.4/sample_config.toml +0 -57
  11. {experiment_server-0.3.4 → experiment_server-0.3.6}/LICENSE.md +0 -0
  12. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/__init__.py +0 -0
  13. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/_server.py +0 -0
  14. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/cli.py +0 -0
  15. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/css/bootstrap-5.2.3.min.css +0 -0
  16. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/index.html +0 -0
  17. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/initconfig.html +0 -0
  18. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/alpinejs3.min.js +0 -0
  19. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/bootstrap-4.5.0.min.js +0 -0
  20. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/fontawesome-1e694dd391.js +0 -0
  21. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/htmx-1.9.10.js +0 -0
  22. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/jquery-3.5.1.min.js +0 -0
  23. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/popper-1.16.0.min.js +0 -0
  24. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/static/js/sweetalert2-11.js +0 -0
  25. {experiment_server-0.3.4 → experiment_server-0.3.6}/experiment_server/utils.py +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: experiment_server
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Server for experiments to get configuarations from
5
- Home-page: https://shariff-faleel.com/experiment_server/
6
5
  License: MIT
7
6
  Keywords: experiment,study-design
8
7
  Author: Ahmed Shariff
@@ -19,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.9
19
18
  Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
22
  Requires-Dist: Jinja2 (>=3.1.2)
23
23
  Requires-Dist: asyncio (>=3.4.3)
24
24
  Requires-Dist: click (>=6.0)
@@ -33,6 +33,7 @@ Requires-Dist: toml (>=0.10.2)
33
33
  Requires-Dist: tornado (>=6.2)
34
34
  Requires-Dist: watchdog (>=2.1.9)
35
35
  Project-URL: Documentation, https://shariff-faleel.com/experiment_server/documentation/
36
+ Project-URL: Homepage, https://shariff-faleel.com/experiment_server/
36
37
  Project-URL: Repository, https://github.com/ahmed-shariff/experiment_server
37
38
  Description-Content-Type: text/markdown
38
39
 
@@ -82,47 +83,90 @@ $ experiment-server new-config-file new_config.toml
82
83
  See example `.toml` below for how the configuration can be defined.
83
84
 
84
85
  ```toml
85
- # The `configuration` table contains the settings of the study/experiment itself
86
+ # The `configuration` table contains settings of the study/experiment itself
86
87
  [configuration]
87
- # The `order` is an array of block names or an array of array of block names.
88
+ # The `order` is an array of block names or an array of array of block
89
+ # names. The `order` also can be a dictionary/table. If it is a
90
+ # dictionary/table, the keys should be participant indices starting
91
+ # from 1. The values should be a list of block names. The keys are
92
+ # the participant indices - when experiment manager is queries with a
93
+ # given participant index, the dictionary/table will be used as a
94
+ # lookup table and the corresponding list of blocks will be used. When
95
+ # a participant index larger than the highest participant index is
96
+ # queries through experiment manager, the modulus of the index will be
97
+ # used to determine which list of conditions should be used. In the
98
+ # following example order with a table/dictionary, participant index 4
99
+ # would get the blocks assigned to participant index 1:
100
+ #
101
+ # order = {1= ["conditionA", "conditionB", "conditionA", "conditionB"], 2= ["conditionB", "conditionA", "conditionB", "conditionA"], 3= ["conditionB", "conditionB", "conditionA", "conditionA"]}
102
+ #
103
+ # The same example as a toml table:
104
+ #
105
+ # [configuration.order]
106
+ # 1= ["conditionA", "conditionB", "conditionA", "conditionB"]
107
+ # 2= ["conditionB", "conditionA", "conditionB", "conditionA"]
108
+ # 3= ["conditionB", "conditionB", "conditionA", "conditionA"]
109
+
88
110
  order = [["conditionA", "conditionB", "conditionA", "conditionB"]]
89
- # The `groups` and `within_groups` are optional keys that allows you to define how the
90
- # conditions specified in `order` will be managed. `groups` would dictate how the top
91
- # level array of `order` will be handled. `within_groups` would dictate how the conditions
92
- # in the nested arrays (if specified) would be managed. These keys can have one
93
- # of the following values.
111
+
112
+ # The `groups_strategy` and `within_groups_strategy` are optional keys
113
+ # that allows you to define how the conditions specified in `order`
114
+ # will be managed.
115
+ # NOTE: This applies only when the `order` is a list.
116
+
117
+ # `groups_strategy` would dictate how the top level array of `order`
118
+ # will be handled. `within_groups_strategy` would dictate how the
119
+ # conditions in the nested arrays (if specified) would be
120
+ # managed. These keys can have one of the following values.
94
121
  # - "latin_square": Apply latin square to balance the values.
95
- # - "randomize": For each participant randomize the order of the values in the array.
122
+ # - "randomize": For each participant randomize the order of the
123
+ # values in the array.
96
124
  # - "as_is": Use the order of the values as specified.
97
125
  # When not specified, the default value is "as_is" for both keys.
98
- groups = "latin_square"
99
- within_groups= "randomize"
100
- # The random seed to use for any randomization. Default seed is 0. The seed will be
101
- # the value of random_seed + participant_index
126
+ groups_strategy = "latin_square"
127
+ within_groups_strategy = "randomize"
128
+
129
+ # The following are optional keys. `init_blocks` is a list of blocks
130
+ # which will be appended to the start and `final_blocks` are a list of
131
+ # blocks that would be appended to the end. The respective strategies
132
+ # dictate the ordering withing the list of init or final blocks. For
133
+ # init and final blocks only the "randomize" and "as_is" are
134
+ # supported. By default, their values are "as_is".
135
+ init_blocks = ["initialBlock"]
136
+ final_blocks = ["finalBlockA", "finalBlockB"]
137
+ init_blocks_strategy = "as_is"
138
+ final_blocks_strategy = "randomize"
139
+
140
+ # The random seed to use for any randomization. Default seed is 0. The
141
+ # seed will be the value of random_seed + participant_index
102
142
  random_seed = 0
103
143
 
104
- # The subtable `variabels` are values that can be used anywhere when defining the blocks.
105
- # Any variable can be used by appending "$" before the variable name in the blocks. See
106
- # below for an exmaple of how variables can be used
144
+ # The subtable `variabels` are values that can be used anywhere when
145
+ # defining the blocks. Any variable can be used by appending "$"
146
+ # before the variable name in the blocks. See below for an exmaple of
147
+ # how variables can be used
107
148
  [configuration.variables]
108
149
  TRIALS_PER_ITEM = 3
109
150
 
110
- # Blocks are defined as an array of tables. Each block must contain `name` and the
111
- # subtable `config`. Optionally, a block can also specify `extends`, whish is a `name` of
112
- # another block. See below for more explanation on how `extends` works
151
+ # Blocks are defined as an array of tables. Each block must contain
152
+ # `name` and the subtable `config`. Optionally, a block can also
153
+ # specify `extends`, whish is a `name` of another block. See below for
154
+ # more explanation on how `extends` works
113
155
 
114
156
  # Block: Condition A
115
157
  [[blocks]]
116
158
  name = "conditionA"
117
159
 
118
- # The `config` subtable can have any key-values. Note that `name` and `participant_index`
119
- # will be added to the `config` when this file is being processed. Hence, those keys
120
- # will be overwritten if used in this subtable.
160
+ # The `config` subtable can have any key-values. Note that `name` and
161
+ # `participant_index` will be added to the `config` when this file is
162
+ # being processed. Hence, those keys will be overwritten if used in
163
+ # this subtable.
121
164
  [blocks.config]
122
165
  trialsPerItem = "$TRIALS_PER_ITEM"
123
166
  param1 = 1
124
- # The value can also be a function call. A function call is represented as a table
125
- # The following function call will be replaced with a call to
167
+ # The value can also be a function call. A function call is
168
+ # represented as a table The following function call will be replaced
169
+ # with a call to
126
170
  # [random.choices](https://docs.python.org/3/library/random.html#random.choices)
127
171
  # See `# Function calls` in README for more information.
128
172
  param2 = { function_name = "choices", args = { population = [1 , 2 , 3 ], k = 2}}
@@ -133,19 +177,48 @@ param3 = { function_name = "choices", args = [[1 , 2 , 3 ]], params = { unique =
133
177
  name = "conditionB"
134
178
  extends = "conditionA"
135
179
 
136
- # Since "conditionB" is extending "conditionA", the keys in the `config` subtable of
137
- # the block "conditionA" not defined in the `config` subtable of "conditionB" will be copied
138
- # to the `config` subtable of "conditionB". In this example, `param1`, `param2` and
180
+ # Since "conditionB" is extending "conditionA", the keys in the
181
+ # `config` subtable of the block "conditionA" not defined in the
182
+ # `config` subtable of "conditionB" will be copied to the `config`
183
+ # subtable of "conditionB". In this example, `param1`, `param2` and
139
184
  # `trialsPerItem` will be copied over here.
140
185
  [blocks.config]
141
186
  param3 = [2]
187
+
188
+ # Block: Initial block
189
+ [[blocks]]
190
+ name = "initialBlock"
191
+ [blocks.config]
192
+ param1 = 1
193
+
194
+ # Block: Final block A
195
+ [[blocks]]
196
+ name = "finalBlockA"
197
+ [blocks.config]
198
+ param1 = 1
199
+
200
+ # Block: Final block B
201
+ [[blocks]]
202
+ name = "finalBlockB"
203
+ [blocks.config]
204
+ param1 = 1
142
205
  ```
143
206
 
144
207
  See [toml spec](https://toml.io/en/v1.0.0) for more information on the format of a toml file.
145
208
 
146
- The above config file, after being processed, would result in the following list of blocks for participant number 1:
209
+ <details>
210
+ <summary>The above config file, after being processed, would result in the following list of blocks for participant number 1:</summary>
147
211
  ```json
148
212
  [
213
+ {
214
+ "name": "initialBlock",
215
+ "config": {
216
+ "param1": 1,
217
+ "participant_index": 1,
218
+ "name": "initialBlock",
219
+ "block_id": 0
220
+ }
221
+ },
149
222
  {
150
223
  "name": "conditionB",
151
224
  "extends": "conditionA",
@@ -157,11 +230,11 @@ The above config file, after being processed, would result in the following list
157
230
  "param1": 1,
158
231
  "param2": [
159
232
  1,
160
- 2
233
+ 3
161
234
  ],
162
235
  "participant_index": 1,
163
236
  "name": "conditionB",
164
- "block_id": 0
237
+ "block_id": 1
165
238
  }
166
239
  },
167
240
  {
@@ -174,11 +247,11 @@ The above config file, after being processed, would result in the following list
174
247
  2
175
248
  ],
176
249
  "param3": [
177
- 3
250
+ 1
178
251
  ],
179
252
  "participant_index": 1,
180
253
  "name": "conditionA",
181
- "block_id": 1
254
+ "block_id": 2
182
255
  }
183
256
  },
184
257
  {
@@ -187,15 +260,15 @@ The above config file, after being processed, would result in the following list
187
260
  "trialsPerItem": 3,
188
261
  "param1": 1,
189
262
  "param2": [
190
- 1,
191
- 1
263
+ 2,
264
+ 3
192
265
  ],
193
266
  "param3": [
194
267
  2
195
268
  ],
196
269
  "participant_index": 1,
197
270
  "name": "conditionA",
198
- "block_id": 2
271
+ "block_id": 3
199
272
  }
200
273
  },
201
274
  {
@@ -208,16 +281,35 @@ The above config file, after being processed, would result in the following list
208
281
  "trialsPerItem": 3,
209
282
  "param1": 1,
210
283
  "param2": [
211
- 3,
212
- 1
284
+ 2,
285
+ 3
213
286
  ],
214
287
  "participant_index": 1,
215
288
  "name": "conditionB",
216
- "block_id": 3
289
+ "block_id": 4
290
+ }
291
+ },
292
+ {
293
+ "name": "finalBlockA",
294
+ "config": {
295
+ "param1": 1,
296
+ "participant_index": 1,
297
+ "name": "finalBlockA",
298
+ "block_id": 5
299
+ }
300
+ },
301
+ {
302
+ "name": "finalBlockB",
303
+ "config": {
304
+ "param1": 1,
305
+ "participant_index": 1,
306
+ "name": "finalBlockB",
307
+ "block_id": 6
217
308
  }
218
309
  }
219
310
  ]
220
311
  ```
312
+ </details>
221
313
 
222
314
  ## Verify config
223
315
  A config file can be validated by running:
@@ -44,47 +44,90 @@ $ experiment-server new-config-file new_config.toml
44
44
  See example `.toml` below for how the configuration can be defined.
45
45
 
46
46
  ```toml
47
- # The `configuration` table contains the settings of the study/experiment itself
47
+ # The `configuration` table contains settings of the study/experiment itself
48
48
  [configuration]
49
- # The `order` is an array of block names or an array of array of block names.
49
+ # The `order` is an array of block names or an array of array of block
50
+ # names. The `order` also can be a dictionary/table. If it is a
51
+ # dictionary/table, the keys should be participant indices starting
52
+ # from 1. The values should be a list of block names. The keys are
53
+ # the participant indices - when experiment manager is queries with a
54
+ # given participant index, the dictionary/table will be used as a
55
+ # lookup table and the corresponding list of blocks will be used. When
56
+ # a participant index larger than the highest participant index is
57
+ # queries through experiment manager, the modulus of the index will be
58
+ # used to determine which list of conditions should be used. In the
59
+ # following example order with a table/dictionary, participant index 4
60
+ # would get the blocks assigned to participant index 1:
61
+ #
62
+ # order = {1= ["conditionA", "conditionB", "conditionA", "conditionB"], 2= ["conditionB", "conditionA", "conditionB", "conditionA"], 3= ["conditionB", "conditionB", "conditionA", "conditionA"]}
63
+ #
64
+ # The same example as a toml table:
65
+ #
66
+ # [configuration.order]
67
+ # 1= ["conditionA", "conditionB", "conditionA", "conditionB"]
68
+ # 2= ["conditionB", "conditionA", "conditionB", "conditionA"]
69
+ # 3= ["conditionB", "conditionB", "conditionA", "conditionA"]
70
+
50
71
  order = [["conditionA", "conditionB", "conditionA", "conditionB"]]
51
- # The `groups` and `within_groups` are optional keys that allows you to define how the
52
- # conditions specified in `order` will be managed. `groups` would dictate how the top
53
- # level array of `order` will be handled. `within_groups` would dictate how the conditions
54
- # in the nested arrays (if specified) would be managed. These keys can have one
55
- # of the following values.
72
+
73
+ # The `groups_strategy` and `within_groups_strategy` are optional keys
74
+ # that allows you to define how the conditions specified in `order`
75
+ # will be managed.
76
+ # NOTE: This applies only when the `order` is a list.
77
+
78
+ # `groups_strategy` would dictate how the top level array of `order`
79
+ # will be handled. `within_groups_strategy` would dictate how the
80
+ # conditions in the nested arrays (if specified) would be
81
+ # managed. These keys can have one of the following values.
56
82
  # - "latin_square": Apply latin square to balance the values.
57
- # - "randomize": For each participant randomize the order of the values in the array.
83
+ # - "randomize": For each participant randomize the order of the
84
+ # values in the array.
58
85
  # - "as_is": Use the order of the values as specified.
59
86
  # When not specified, the default value is "as_is" for both keys.
60
- groups = "latin_square"
61
- within_groups= "randomize"
62
- # The random seed to use for any randomization. Default seed is 0. The seed will be
63
- # the value of random_seed + participant_index
87
+ groups_strategy = "latin_square"
88
+ within_groups_strategy = "randomize"
89
+
90
+ # The following are optional keys. `init_blocks` is a list of blocks
91
+ # which will be appended to the start and `final_blocks` are a list of
92
+ # blocks that would be appended to the end. The respective strategies
93
+ # dictate the ordering withing the list of init or final blocks. For
94
+ # init and final blocks only the "randomize" and "as_is" are
95
+ # supported. By default, their values are "as_is".
96
+ init_blocks = ["initialBlock"]
97
+ final_blocks = ["finalBlockA", "finalBlockB"]
98
+ init_blocks_strategy = "as_is"
99
+ final_blocks_strategy = "randomize"
100
+
101
+ # The random seed to use for any randomization. Default seed is 0. The
102
+ # seed will be the value of random_seed + participant_index
64
103
  random_seed = 0
65
104
 
66
- # The subtable `variabels` are values that can be used anywhere when defining the blocks.
67
- # Any variable can be used by appending "$" before the variable name in the blocks. See
68
- # below for an exmaple of how variables can be used
105
+ # The subtable `variabels` are values that can be used anywhere when
106
+ # defining the blocks. Any variable can be used by appending "$"
107
+ # before the variable name in the blocks. See below for an exmaple of
108
+ # how variables can be used
69
109
  [configuration.variables]
70
110
  TRIALS_PER_ITEM = 3
71
111
 
72
- # Blocks are defined as an array of tables. Each block must contain `name` and the
73
- # subtable `config`. Optionally, a block can also specify `extends`, whish is a `name` of
74
- # another block. See below for more explanation on how `extends` works
112
+ # Blocks are defined as an array of tables. Each block must contain
113
+ # `name` and the subtable `config`. Optionally, a block can also
114
+ # specify `extends`, whish is a `name` of another block. See below for
115
+ # more explanation on how `extends` works
75
116
 
76
117
  # Block: Condition A
77
118
  [[blocks]]
78
119
  name = "conditionA"
79
120
 
80
- # The `config` subtable can have any key-values. Note that `name` and `participant_index`
81
- # will be added to the `config` when this file is being processed. Hence, those keys
82
- # will be overwritten if used in this subtable.
121
+ # The `config` subtable can have any key-values. Note that `name` and
122
+ # `participant_index` will be added to the `config` when this file is
123
+ # being processed. Hence, those keys will be overwritten if used in
124
+ # this subtable.
83
125
  [blocks.config]
84
126
  trialsPerItem = "$TRIALS_PER_ITEM"
85
127
  param1 = 1
86
- # The value can also be a function call. A function call is represented as a table
87
- # The following function call will be replaced with a call to
128
+ # The value can also be a function call. A function call is
129
+ # represented as a table The following function call will be replaced
130
+ # with a call to
88
131
  # [random.choices](https://docs.python.org/3/library/random.html#random.choices)
89
132
  # See `# Function calls` in README for more information.
90
133
  param2 = { function_name = "choices", args = { population = [1 , 2 , 3 ], k = 2}}
@@ -95,19 +138,48 @@ param3 = { function_name = "choices", args = [[1 , 2 , 3 ]], params = { unique =
95
138
  name = "conditionB"
96
139
  extends = "conditionA"
97
140
 
98
- # Since "conditionB" is extending "conditionA", the keys in the `config` subtable of
99
- # the block "conditionA" not defined in the `config` subtable of "conditionB" will be copied
100
- # to the `config` subtable of "conditionB". In this example, `param1`, `param2` and
141
+ # Since "conditionB" is extending "conditionA", the keys in the
142
+ # `config` subtable of the block "conditionA" not defined in the
143
+ # `config` subtable of "conditionB" will be copied to the `config`
144
+ # subtable of "conditionB". In this example, `param1`, `param2` and
101
145
  # `trialsPerItem` will be copied over here.
102
146
  [blocks.config]
103
147
  param3 = [2]
148
+
149
+ # Block: Initial block
150
+ [[blocks]]
151
+ name = "initialBlock"
152
+ [blocks.config]
153
+ param1 = 1
154
+
155
+ # Block: Final block A
156
+ [[blocks]]
157
+ name = "finalBlockA"
158
+ [blocks.config]
159
+ param1 = 1
160
+
161
+ # Block: Final block B
162
+ [[blocks]]
163
+ name = "finalBlockB"
164
+ [blocks.config]
165
+ param1 = 1
104
166
  ```
105
167
 
106
168
  See [toml spec](https://toml.io/en/v1.0.0) for more information on the format of a toml file.
107
169
 
108
- The above config file, after being processed, would result in the following list of blocks for participant number 1:
170
+ <details>
171
+ <summary>The above config file, after being processed, would result in the following list of blocks for participant number 1:</summary>
109
172
  ```json
110
173
  [
174
+ {
175
+ "name": "initialBlock",
176
+ "config": {
177
+ "param1": 1,
178
+ "participant_index": 1,
179
+ "name": "initialBlock",
180
+ "block_id": 0
181
+ }
182
+ },
111
183
  {
112
184
  "name": "conditionB",
113
185
  "extends": "conditionA",
@@ -119,11 +191,11 @@ The above config file, after being processed, would result in the following list
119
191
  "param1": 1,
120
192
  "param2": [
121
193
  1,
122
- 2
194
+ 3
123
195
  ],
124
196
  "participant_index": 1,
125
197
  "name": "conditionB",
126
- "block_id": 0
198
+ "block_id": 1
127
199
  }
128
200
  },
129
201
  {
@@ -136,11 +208,11 @@ The above config file, after being processed, would result in the following list
136
208
  2
137
209
  ],
138
210
  "param3": [
139
- 3
211
+ 1
140
212
  ],
141
213
  "participant_index": 1,
142
214
  "name": "conditionA",
143
- "block_id": 1
215
+ "block_id": 2
144
216
  }
145
217
  },
146
218
  {
@@ -149,15 +221,15 @@ The above config file, after being processed, would result in the following list
149
221
  "trialsPerItem": 3,
150
222
  "param1": 1,
151
223
  "param2": [
152
- 1,
153
- 1
224
+ 2,
225
+ 3
154
226
  ],
155
227
  "param3": [
156
228
  2
157
229
  ],
158
230
  "participant_index": 1,
159
231
  "name": "conditionA",
160
- "block_id": 2
232
+ "block_id": 3
161
233
  }
162
234
  },
163
235
  {
@@ -170,16 +242,35 @@ The above config file, after being processed, would result in the following list
170
242
  "trialsPerItem": 3,
171
243
  "param1": 1,
172
244
  "param2": [
173
- 3,
174
- 1
245
+ 2,
246
+ 3
175
247
  ],
176
248
  "participant_index": 1,
177
249
  "name": "conditionB",
178
- "block_id": 3
250
+ "block_id": 4
251
+ }
252
+ },
253
+ {
254
+ "name": "finalBlockA",
255
+ "config": {
256
+ "param1": 1,
257
+ "participant_index": 1,
258
+ "name": "finalBlockA",
259
+ "block_id": 5
260
+ }
261
+ },
262
+ {
263
+ "name": "finalBlockB",
264
+ "config": {
265
+ "param1": 1,
266
+ "participant_index": 1,
267
+ "name": "finalBlockB",
268
+ "block_id": 6
179
269
  }
180
270
  }
181
271
  ]
182
272
  ```
273
+ </details>
183
274
 
184
275
  ## Verify config
185
276
  A config file can be validated by running: