canvas 0.63.0__py3-none-any.whl → 0.89.0__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.
Files changed (185) hide show
  1. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/METADATA +4 -1
  2. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/RECORD +184 -98
  3. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/WHEEL +1 -1
  4. canvas_cli/apps/emit/event_fixtures/UNKNOWN.ndjson +1 -0
  5. canvas_cli/apps/logs/logs.py +386 -22
  6. canvas_cli/main.py +3 -1
  7. canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/test_models.py +46 -4
  8. canvas_cli/utils/context/context.py +13 -13
  9. canvas_cli/utils/validators/manifest_schema.py +26 -1
  10. canvas_generated/messages/effects_pb2.py +5 -5
  11. canvas_generated/messages/effects_pb2.pyi +108 -2
  12. canvas_generated/messages/events_pb2.py +6 -6
  13. canvas_generated/messages/events_pb2.pyi +282 -2
  14. canvas_sdk/clients/__init__.py +1 -0
  15. canvas_sdk/clients/llms/__init__.py +17 -0
  16. canvas_sdk/clients/llms/libraries/__init__.py +11 -0
  17. canvas_sdk/clients/llms/libraries/llm_anthropic.py +87 -0
  18. canvas_sdk/clients/llms/libraries/llm_api.py +143 -0
  19. canvas_sdk/clients/llms/libraries/llm_google.py +92 -0
  20. canvas_sdk/clients/llms/libraries/llm_openai.py +98 -0
  21. canvas_sdk/clients/llms/structures/__init__.py +9 -0
  22. canvas_sdk/clients/llms/structures/llm_response.py +33 -0
  23. canvas_sdk/clients/llms/structures/llm_tokens.py +53 -0
  24. canvas_sdk/clients/llms/structures/llm_turn.py +47 -0
  25. canvas_sdk/clients/llms/structures/settings/__init__.py +13 -0
  26. canvas_sdk/clients/llms/structures/settings/llm_settings.py +27 -0
  27. canvas_sdk/clients/llms/structures/settings/llm_settings_anthropic.py +43 -0
  28. canvas_sdk/clients/llms/structures/settings/llm_settings_gemini.py +40 -0
  29. canvas_sdk/clients/llms/structures/settings/llm_settings_gpt4.py +40 -0
  30. canvas_sdk/clients/llms/structures/settings/llm_settings_gpt5.py +48 -0
  31. canvas_sdk/clients/third_party.py +3 -0
  32. canvas_sdk/commands/__init__.py +12 -0
  33. canvas_sdk/commands/base.py +33 -2
  34. canvas_sdk/commands/commands/adjust_prescription.py +4 -0
  35. canvas_sdk/commands/commands/custom_command.py +86 -0
  36. canvas_sdk/commands/commands/family_history.py +17 -1
  37. canvas_sdk/commands/commands/immunization_statement.py +42 -2
  38. canvas_sdk/commands/commands/medication_statement.py +16 -1
  39. canvas_sdk/commands/commands/past_surgical_history.py +16 -1
  40. canvas_sdk/commands/commands/perform.py +18 -1
  41. canvas_sdk/commands/commands/prescribe.py +8 -9
  42. canvas_sdk/commands/commands/refill.py +5 -5
  43. canvas_sdk/commands/commands/resolve_condition.py +5 -5
  44. canvas_sdk/commands/commands/review/__init__.py +3 -0
  45. canvas_sdk/commands/commands/review/base.py +72 -0
  46. canvas_sdk/commands/commands/review/imaging.py +13 -0
  47. canvas_sdk/commands/commands/review/lab.py +13 -0
  48. canvas_sdk/commands/commands/review/referral.py +13 -0
  49. canvas_sdk/commands/commands/review/uncategorized_document.py +13 -0
  50. canvas_sdk/commands/validation.py +43 -0
  51. canvas_sdk/effects/batch_originate.py +22 -0
  52. canvas_sdk/effects/calendar/__init__.py +13 -3
  53. canvas_sdk/effects/calendar/{create_calendar.py → calendar.py} +19 -5
  54. canvas_sdk/effects/calendar/event.py +172 -0
  55. canvas_sdk/effects/claim_label.py +93 -0
  56. canvas_sdk/effects/claim_line_item.py +47 -0
  57. canvas_sdk/effects/claim_queue.py +49 -0
  58. canvas_sdk/effects/fax/__init__.py +3 -0
  59. canvas_sdk/effects/fax/base.py +77 -0
  60. canvas_sdk/effects/fax/note.py +42 -0
  61. canvas_sdk/effects/metadata.py +15 -1
  62. canvas_sdk/effects/note/__init__.py +8 -1
  63. canvas_sdk/effects/note/appointment.py +135 -7
  64. canvas_sdk/effects/note/base.py +17 -0
  65. canvas_sdk/effects/note/message.py +22 -14
  66. canvas_sdk/effects/note/note.py +150 -1
  67. canvas_sdk/effects/observation/__init__.py +11 -0
  68. canvas_sdk/effects/observation/base.py +206 -0
  69. canvas_sdk/effects/patient/__init__.py +2 -0
  70. canvas_sdk/effects/patient/base.py +8 -0
  71. canvas_sdk/effects/payment/__init__.py +11 -0
  72. canvas_sdk/effects/payment/base.py +355 -0
  73. canvas_sdk/effects/payment/post_claim_payment.py +49 -0
  74. canvas_sdk/effects/send_contact_verification.py +42 -0
  75. canvas_sdk/effects/task/__init__.py +2 -1
  76. canvas_sdk/effects/task/task.py +30 -0
  77. canvas_sdk/effects/validation/__init__.py +3 -0
  78. canvas_sdk/effects/validation/base.py +92 -0
  79. canvas_sdk/events/base.py +15 -0
  80. canvas_sdk/handlers/application.py +7 -7
  81. canvas_sdk/handlers/simple_api/api.py +1 -4
  82. canvas_sdk/handlers/simple_api/websocket.py +1 -4
  83. canvas_sdk/handlers/utils.py +14 -0
  84. canvas_sdk/questionnaires/utils.py +1 -0
  85. canvas_sdk/templates/utils.py +17 -4
  86. canvas_sdk/test_utils/factories/FACTORY_GUIDE.md +362 -0
  87. canvas_sdk/test_utils/factories/__init__.py +115 -0
  88. canvas_sdk/test_utils/factories/calendar.py +24 -0
  89. canvas_sdk/test_utils/factories/claim.py +81 -0
  90. canvas_sdk/test_utils/factories/claim_diagnosis_code.py +16 -0
  91. canvas_sdk/test_utils/factories/coverage.py +17 -0
  92. canvas_sdk/test_utils/factories/imaging.py +74 -0
  93. canvas_sdk/test_utils/factories/lab.py +192 -0
  94. canvas_sdk/test_utils/factories/medication_history.py +75 -0
  95. canvas_sdk/test_utils/factories/note.py +52 -0
  96. canvas_sdk/test_utils/factories/organization.py +50 -0
  97. canvas_sdk/test_utils/factories/practicelocation.py +88 -0
  98. canvas_sdk/test_utils/factories/referral.py +81 -0
  99. canvas_sdk/test_utils/factories/staff.py +111 -0
  100. canvas_sdk/test_utils/factories/task.py +66 -0
  101. canvas_sdk/test_utils/factories/uncategorized_clinical_document.py +48 -0
  102. canvas_sdk/utils/metrics.py +4 -1
  103. canvas_sdk/v1/data/__init__.py +66 -7
  104. canvas_sdk/v1/data/allergy_intolerance.py +5 -11
  105. canvas_sdk/v1/data/appointment.py +18 -4
  106. canvas_sdk/v1/data/assessment.py +2 -12
  107. canvas_sdk/v1/data/banner_alert.py +2 -4
  108. canvas_sdk/v1/data/base.py +53 -14
  109. canvas_sdk/v1/data/billing.py +8 -11
  110. canvas_sdk/v1/data/calendar.py +64 -0
  111. canvas_sdk/v1/data/care_team.py +4 -10
  112. canvas_sdk/v1/data/claim.py +172 -66
  113. canvas_sdk/v1/data/claim_diagnosis_code.py +19 -0
  114. canvas_sdk/v1/data/claim_line_item.py +2 -5
  115. canvas_sdk/v1/data/coding.py +19 -0
  116. canvas_sdk/v1/data/command.py +2 -4
  117. canvas_sdk/v1/data/common.py +10 -0
  118. canvas_sdk/v1/data/compound_medication.py +3 -4
  119. canvas_sdk/v1/data/condition.py +4 -9
  120. canvas_sdk/v1/data/coverage.py +66 -26
  121. canvas_sdk/v1/data/detected_issue.py +20 -20
  122. canvas_sdk/v1/data/device.py +2 -14
  123. canvas_sdk/v1/data/discount.py +2 -5
  124. canvas_sdk/v1/data/encounter.py +44 -0
  125. canvas_sdk/v1/data/facility.py +1 -0
  126. canvas_sdk/v1/data/goal.py +2 -14
  127. canvas_sdk/v1/data/imaging.py +4 -30
  128. canvas_sdk/v1/data/immunization.py +7 -15
  129. canvas_sdk/v1/data/lab.py +12 -65
  130. canvas_sdk/v1/data/line_item_transaction.py +2 -5
  131. canvas_sdk/v1/data/medication.py +3 -8
  132. canvas_sdk/v1/data/medication_history.py +142 -0
  133. canvas_sdk/v1/data/medication_statement.py +41 -0
  134. canvas_sdk/v1/data/message.py +4 -8
  135. canvas_sdk/v1/data/note.py +37 -38
  136. canvas_sdk/v1/data/observation.py +9 -36
  137. canvas_sdk/v1/data/organization.py +70 -9
  138. canvas_sdk/v1/data/patient.py +8 -12
  139. canvas_sdk/v1/data/patient_consent.py +4 -14
  140. canvas_sdk/v1/data/payment_collection.py +2 -5
  141. canvas_sdk/v1/data/posting.py +3 -9
  142. canvas_sdk/v1/data/practicelocation.py +66 -7
  143. canvas_sdk/v1/data/protocol_override.py +3 -4
  144. canvas_sdk/v1/data/protocol_result.py +3 -3
  145. canvas_sdk/v1/data/questionnaire.py +10 -26
  146. canvas_sdk/v1/data/reason_for_visit.py +2 -6
  147. canvas_sdk/v1/data/referral.py +41 -17
  148. canvas_sdk/v1/data/staff.py +34 -26
  149. canvas_sdk/v1/data/stop_medication_event.py +27 -0
  150. canvas_sdk/v1/data/task.py +30 -11
  151. canvas_sdk/v1/data/team.py +2 -4
  152. canvas_sdk/v1/data/uncategorized_clinical_document.py +84 -0
  153. canvas_sdk/v1/data/user.py +14 -0
  154. canvas_sdk/v1/data/utils.py +5 -0
  155. canvas_sdk/value_set/v2026/__init__.py +1 -0
  156. canvas_sdk/value_set/v2026/adverse_event.py +157 -0
  157. canvas_sdk/value_set/v2026/allergy.py +116 -0
  158. canvas_sdk/value_set/v2026/assessment.py +466 -0
  159. canvas_sdk/value_set/v2026/communication.py +496 -0
  160. canvas_sdk/value_set/v2026/condition.py +52934 -0
  161. canvas_sdk/value_set/v2026/device.py +315 -0
  162. canvas_sdk/value_set/v2026/diagnostic_study.py +5243 -0
  163. canvas_sdk/value_set/v2026/encounter.py +2714 -0
  164. canvas_sdk/value_set/v2026/immunization.py +297 -0
  165. canvas_sdk/value_set/v2026/individual_characteristic.py +339 -0
  166. canvas_sdk/value_set/v2026/intervention.py +1703 -0
  167. canvas_sdk/value_set/v2026/laboratory_test.py +1831 -0
  168. canvas_sdk/value_set/v2026/medication.py +8218 -0
  169. canvas_sdk/value_set/v2026/no_qdm_category_assigned.py +26493 -0
  170. canvas_sdk/value_set/v2026/physical_exam.py +342 -0
  171. canvas_sdk/value_set/v2026/procedure.py +27869 -0
  172. canvas_sdk/value_set/v2026/symptom.py +625 -0
  173. logger/logger.py +30 -31
  174. logger/logstash.py +282 -0
  175. logger/pubsub.py +26 -0
  176. plugin_runner/allowed-module-imports.json +940 -9
  177. plugin_runner/generate_allowed_imports.py +1 -0
  178. plugin_runner/installation.py +2 -2
  179. plugin_runner/plugin_runner.py +21 -24
  180. plugin_runner/sandbox.py +34 -0
  181. protobufs/canvas_generated/messages/effects.proto +65 -0
  182. protobufs/canvas_generated/messages/events.proto +150 -51
  183. settings.py +27 -11
  184. canvas_sdk/effects/calendar/create_event.py +0 -43
  185. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/entry_points.txt +0 -0
@@ -7,6 +7,7 @@ from typing import Any
7
7
 
8
8
  CANVAS_TOP_LEVEL_MODULES = (
9
9
  "canvas_sdk.caching",
10
+ "canvas_sdk.clients",
10
11
  "canvas_sdk.commands",
11
12
  "canvas_sdk.effects",
12
13
  "canvas_sdk.events",
@@ -170,7 +170,7 @@ def install_plugin(plugin_name: str, attributes: PluginAttributes) -> None:
170
170
 
171
171
  install_plugin_secrets(plugin_name=plugin_name, secrets=attributes["secrets"])
172
172
  except Exception as e:
173
- log.error(f'Failed to install plugin "{plugin_name}", version {attributes["version"]}: {e}')
173
+ log.exception(f'Failed to install plugin "{plugin_name}", version {attributes["version"]}')
174
174
 
175
175
  sentry_sdk.capture_exception(e)
176
176
 
@@ -190,7 +190,7 @@ def extract_plugin(plugin_file_path: Path, plugin_installation_path: Path) -> No
190
190
  archive = tarfile.TarFile.open(fileobj=file)
191
191
  archive.extractall(plugin_installation_path, filter="data")
192
192
  except tarfile.ReadError as e:
193
- log.error(f"Unreadable tar archive: '{plugin_file_path}'")
193
+ log.exception(f"Unreadable tar archive: '{plugin_file_path}'")
194
194
  sentry_sdk.capture_exception(e)
195
195
 
196
196
  raise InvalidPluginFormat from e
@@ -6,7 +6,6 @@ import pickle
6
6
  import pkgutil
7
7
  import sys
8
8
  import threading
9
- import traceback
10
9
  from collections import defaultdict
11
10
  from collections.abc import Iterable
12
11
  from concurrent.futures import ThreadPoolExecutor
@@ -42,6 +41,7 @@ from canvas_sdk.effects.simple_api import Response
42
41
  from canvas_sdk.events import Event, EventRequest, EventResponse, EventType
43
42
  from canvas_sdk.handlers.simple_api.websocket import DenyConnection
44
43
  from canvas_sdk.protocols import ClinicalQualityMeasure
44
+ from canvas_sdk.templates.utils import _engine_for_plugin
45
45
  from canvas_sdk.utils import metrics
46
46
  from canvas_sdk.utils.metrics import measured
47
47
  from logger import log
@@ -96,10 +96,6 @@ if SENTRY_DSN:
96
96
  global_scope.set_tag("source", "plugin-runner")
97
97
  global_scope.set_tag("production_customer", "yes" if IS_PRODUCTION_CUSTOMER else "no")
98
98
 
99
- # when we import plugins we'll use the module name directly so we need to add the plugin
100
- # directory to the path
101
- sys.path.append(PLUGIN_DIRECTORY)
102
-
103
99
  Plugin = TypedDict(
104
100
  "Plugin",
105
101
  {
@@ -231,7 +227,7 @@ class PluginRunner(PluginRunnerServicer):
231
227
  p for p in relevant_plugins if p.startswith(f"{plugin_name}:")
232
228
  ]
233
229
  except Exception as ex:
234
- log.error(
230
+ log.exception(
235
231
  f"Failed to decode identifier for event {event_name} with context {event.context}"
236
232
  )
237
233
  sentry_sdk.capture_exception(ex)
@@ -281,6 +277,8 @@ class PluginRunner(PluginRunnerServicer):
281
277
  plugin_name=base_plugin_name,
282
278
  classname=classname,
283
279
  handler_name=handler_name,
280
+ actor=event.actor.id,
281
+ source=event.source,
284
282
  )
285
283
  for effect in _effects
286
284
  ]
@@ -292,12 +290,7 @@ class PluginRunner(PluginRunnerServicer):
292
290
  log.info(f"{plugin_name}.compute() completed.")
293
291
 
294
292
  except Exception as e:
295
- log.error(f"Encountered exception in plugin {plugin_name}:")
296
-
297
- for error_line_with_newlines in traceback.format_exception(e):
298
- for error_line in error_line_with_newlines.split("\n"):
299
- log.error(error_line)
300
-
293
+ log.exception(f"Encountered exception in plugin {plugin_name}")
301
294
  sentry_sdk.capture_exception(e)
302
295
  continue
303
296
 
@@ -419,6 +412,9 @@ def synchronize_plugins(run_once: bool = False) -> None:
419
412
  if "action" not in data:
420
413
  continue
421
414
 
415
+ # clear the template engine cache so that any template changes
416
+ # from plugins are picked up
417
+ _engine_for_plugin.cache_clear()
422
418
  plugin_name = data.get("plugin", None)
423
419
  try:
424
420
  if data["action"] == "reload":
@@ -429,6 +425,7 @@ def synchronize_plugins(run_once: bool = False) -> None:
429
425
  log.info(
430
426
  f'synchronize_plugins: installing/reloading plugin "{plugin_name}" for action=reload'
431
427
  )
428
+ unload_plugin(plugin_name)
432
429
  install_plugin(plugin_name, attributes=plugin)
433
430
  plugin_dir = pathlib.Path(PLUGIN_DIRECTORY) / plugin_name
434
431
  load_plugin(plugin_dir.resolve())
@@ -451,7 +448,7 @@ def synchronize_plugins(run_once: bool = False) -> None:
451
448
  if plugin_name:
452
449
  message += f' for plugin "{plugin_name}"'
453
450
 
454
- log.error(f"synchronize_plugins: {message}: {e}")
451
+ log.exception(f"synchronize_plugins: {message}")
455
452
  sentry_sdk.capture_exception(e)
456
453
 
457
454
  if run_once:
@@ -468,7 +465,7 @@ def synchronize_plugins_and_report_errors() -> None:
468
465
  try:
469
466
  synchronize_plugins()
470
467
  except Exception as e:
471
- log.error(f"synchronize_plugins: error: {e}")
468
+ log.exception("synchronize_plugins: error")
472
469
  sentry_sdk.capture_exception(e)
473
470
 
474
471
  # don't crush redis if we're retrying in a tight loop
@@ -569,7 +566,7 @@ def load_or_reload_plugin(path: pathlib.Path) -> bool:
569
566
  try:
570
567
  manifest_json: PluginManifest = json.loads(manifest_json_str)
571
568
  except Exception as e:
572
- log.error(f'Unable to load plugin "{name}": {e}')
569
+ log.exception(f'Unable to load plugin "{name}"')
573
570
  sentry_sdk.capture_exception(e)
574
571
 
575
572
  return False
@@ -581,7 +578,7 @@ def load_or_reload_plugin(path: pathlib.Path) -> bool:
581
578
  try:
582
579
  secrets_json = json.load(secrets_file.open())
583
580
  except Exception as e:
584
- log.error(f'Unable to load secrets for plugin "{name}": {str(e)}')
581
+ log.exception(f'Unable to load secrets for plugin "{name}"')
585
582
  sentry_sdk.capture_exception(e)
586
583
 
587
584
  # TODO add existing schema validation from Michela here
@@ -590,7 +587,7 @@ def load_or_reload_plugin(path: pathlib.Path) -> bool:
590
587
  "components"
591
588
  ].get("applications", [])
592
589
  except Exception as e:
593
- log.error(f'Unable to load plugin "{name}": {str(e)}')
590
+ log.exception(f'Unable to load plugin "{name}"')
594
591
  sentry_sdk.capture_exception(e)
595
592
 
596
593
  return False
@@ -604,7 +601,7 @@ def load_or_reload_plugin(path: pathlib.Path) -> bool:
604
601
  handler_module, handler_class = handler["class"].split(":")
605
602
  name_and_class = f"{name}:{handler_module}:{handler_class}"
606
603
  except ValueError as e:
607
- log.error(f'Unable to parse class for plugin "{name}": "{handler["class"]}"')
604
+ log.exception(f'Unable to parse class for plugin "{name}": "{handler["class"]}"')
608
605
  sentry_sdk.capture_exception(e)
609
606
 
610
607
  any_failed = True
@@ -634,13 +631,8 @@ def load_or_reload_plugin(path: pathlib.Path) -> bool:
634
631
  "secrets": secrets_json,
635
632
  }
636
633
  except Exception as e:
637
- log.error(f'Error importing module "{name_and_class}": {e}')
638
-
639
- for error_line in traceback.format_exception(e):
640
- log.error(error_line)
641
-
634
+ log.exception(f"Error importing module '{name_and_class}'")
642
635
  sentry_sdk.capture_exception(e)
643
-
644
636
  any_failed = True
645
637
 
646
638
  return not any_failed
@@ -698,6 +690,11 @@ def load_plugins(specified_plugin_paths: list[str] | None = None) -> None:
698
690
  path_to_append = pathlib.Path(".") / plugin_path.parent
699
691
  sys.path.append(path_to_append.as_posix())
700
692
  else:
693
+ # Add plugin directory to path only when actually loading plugins (not at module import time)
694
+ # to avoid polluting Python's import cache during test collection
695
+ if PLUGIN_DIRECTORY not in sys.path:
696
+ sys.path.append(PLUGIN_DIRECTORY)
697
+
701
698
  candidates = os.listdir(PLUGIN_DIRECTORY)
702
699
 
703
700
  # convert to Paths
plugin_runner/sandbox.py CHANGED
@@ -90,6 +90,18 @@ STANDARD_LIBRARY_MODULES = {
90
90
  "Counter",
91
91
  "defaultdict",
92
92
  },
93
+ "dataclasses": {
94
+ "asdict",
95
+ "astuple",
96
+ "dataclass",
97
+ "field",
98
+ "Field",
99
+ "fields",
100
+ "InitVar",
101
+ "is_dataclass",
102
+ "make_dataclass",
103
+ "replace",
104
+ },
93
105
  "datetime": {
94
106
  "date",
95
107
  "datetime",
@@ -126,6 +138,7 @@ STANDARD_LIBRARY_MODULES = {
126
138
  "json": {
127
139
  "dumps",
128
140
  "loads",
141
+ "JSONDecodeError",
129
142
  },
130
143
  "operator": {
131
144
  "and_",
@@ -168,6 +181,7 @@ STANDARD_LIBRARY_MODULES = {
168
181
  "Tuple",
169
182
  "Type",
170
183
  "TypedDict",
184
+ "TypeGuard",
171
185
  "Union",
172
186
  },
173
187
  "urllib": {
@@ -181,6 +195,9 @@ STANDARD_LIBRARY_MODULES = {
181
195
  "uuid4",
182
196
  "UUID",
183
197
  },
198
+ "defusedxml.ElementTree": {
199
+ "fromstring",
200
+ },
184
201
  "zoneinfo": {
185
202
  "ZoneInfo",
186
203
  },
@@ -194,23 +211,39 @@ THIRD_PARTY_MODULES = {
194
211
  "utcnow",
195
212
  },
196
213
  "django.db.models": {
214
+ "Avg",
197
215
  "BigIntegerField",
198
216
  "Case",
199
217
  "CharField",
200
218
  "Count",
219
+ "Exists",
201
220
  "F",
202
221
  "IntegerField",
222
+ "Max",
223
+ "Min",
203
224
  "Model", # remove when hyperscribe no longer needs it
225
+ "OuterRef",
226
+ "Prefetch",
204
227
  "Q",
228
+ "Subquery",
229
+ "Sum",
205
230
  "Value",
206
231
  "When",
207
232
  },
208
233
  "django.db.models.expressions": {
209
234
  "Case",
235
+ "Exists",
236
+ "OuterRef",
237
+ "Subquery",
210
238
  "Value",
211
239
  "When",
212
240
  },
241
+ "django.db.models.functions": {
242
+ "Coalesce",
243
+ "Trim",
244
+ },
213
245
  "django.db.models.query": {
246
+ "Prefetch",
214
247
  "QuerySet",
215
248
  },
216
249
  "django.utils.functional": {
@@ -658,6 +691,7 @@ class Sandbox:
658
691
  "property": builtins.property,
659
692
  "reversed": builtins.reversed,
660
693
  "staticmethod": builtins.staticmethod,
694
+ "sum": builtins.sum,
661
695
  "super": builtins.super,
662
696
  "vars": builtins.vars,
663
697
  },
@@ -55,6 +55,7 @@ enum EffectType {
55
55
  COMMIT_PRESCRIBE_COMMAND = 39;
56
56
  ENTER_IN_ERROR_PRESCRIBE_COMMAND = 40;
57
57
  SEND_PRESCRIBE_COMMAND = 1305;
58
+ REVIEW_PRESCRIBE_COMMAND = 1309;
58
59
 
59
60
  ORIGINATE_QUESTIONNAIRE_COMMAND = 41;
60
61
  EDIT_QUESTIONNAIRE_COMMAND = 42;
@@ -126,6 +127,7 @@ enum EffectType {
126
127
  CREATE_TASK = 100;
127
128
  UPDATE_TASK = 101;
128
129
  CREATE_TASK_COMMENT = 102;
130
+ UPSERT_TASK_METADATA = 111;
129
131
 
130
132
  ORIGINATE_MEDICAL_HISTORY_COMMAND = 103;
131
133
  EDIT_MEDICAL_HISTORY_COMMAND = 104;
@@ -147,6 +149,7 @@ enum EffectType {
147
149
  COMMIT_REFILL_COMMAND = 116;
148
150
  ENTER_IN_ERROR_REFILL_COMMAND = 117;
149
151
  SEND_REFILL_COMMAND = 1308;
152
+ REVIEW_REFILL_COMMAND = 1310;
150
153
 
151
154
  ORIGINATE_VITALS_COMMAND = 118;
152
155
  EDIT_VITALS_COMMAND = 119;
@@ -181,6 +184,7 @@ enum EffectType {
181
184
  CREATE_QUESTIONNAIRE_RESULT = 138;
182
185
 
183
186
  ANNOTATE_PATIENT_CHART_CONDITION_RESULTS = 200;
187
+ ANNOTATE_PATIENT_CHART_DETECTED_ISSUE_RESULTS = 201;
184
188
 
185
189
  ANNOTATE_CLAIM_CONDITION_RESULTS = 300;
186
190
 
@@ -236,6 +240,7 @@ enum EffectType {
236
240
  COMMIT_ADJUST_PRESCRIPTION_COMMAND = 1303;
237
241
  ENTER_IN_ERROR_ADJUST_PRESCRIPTION_COMMAND = 1304;
238
242
  SEND_ADJUST_PRESCRIPTION_COMMAND = 1307;
243
+ REVIEW_ADJUST_PRESCRIPTION_COMMAND = 1311;
239
244
 
240
245
  ORIGINATE_CHART_SECTION_REVIEW_COMMAND = 1400;
241
246
 
@@ -245,7 +250,32 @@ enum EffectType {
245
250
  COMMIT_IMMUNIZATION_STATEMENT_COMMAND = 1503;
246
251
  ENTER_IN_ERROR_IMMUNIZATION_STATEMENT_COMMAND = 1504;
247
252
 
253
+ ORIGINATE_LAB_REVIEW_COMMAND = 1505;
254
+ EDIT_LAB_REVIEW_COMMAND = 1506;
255
+ DELETE_LAB_REVIEW_COMMAND = 1507;
256
+ COMMIT_LAB_REVIEW_COMMAND = 1508;
257
+ ENTER_IN_ERROR_LAB_REVIEW_COMMAND = 1509;
258
+
259
+ ORIGINATE_IMAGING_REVIEW_COMMAND = 1510;
260
+ EDIT_IMAGING_REVIEW_COMMAND = 1511;
261
+ DELETE_IMAGING_REVIEW_COMMAND = 1512;
262
+ COMMIT_IMAGING_REVIEW_COMMAND = 1513;
263
+ ENTER_IN_ERROR_IMAGING_REVIEW_COMMAND = 1514;
264
+
265
+ ORIGINATE_REFERRAL_REVIEW_COMMAND = 1515;
266
+ EDIT_REFERRAL_REVIEW_COMMAND = 1516;
267
+ DELETE_REFERRAL_REVIEW_COMMAND = 1517;
268
+ COMMIT_REFERRAL_REVIEW_COMMAND = 1518;
269
+ ENTER_IN_ERROR_REFERRAL_REVIEW_COMMAND = 1519;
270
+
271
+ ORIGINATE_UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND = 1520;
272
+ EDIT_UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND = 1521;
273
+ DELETE_UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND = 1522;
274
+ COMMIT_UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND = 1523;
275
+ ENTER_IN_ERROR_UNCATEGORIZED_DOCUMENT_REVIEW_COMMAND = 1524;
276
+
248
277
  COMMAND_AVAILABLE_ACTIONS_RESULTS = 1600;
278
+ COMMAND_VALIDATION_ERRORS = 1601;
249
279
 
250
280
  SHOW_ACTION_BUTTON = 1000;
251
281
 
@@ -254,6 +284,7 @@ enum EffectType {
254
284
  PATIENT_PORTAL__APPOINTMENT_IS_RESCHEDULABLE = 2002;
255
285
  PATIENT_PORTAL__APPOINTMENT_SHOW_MEETING_LINK = 2003;
256
286
  PATIENT_PORTAL__SEND_INVITE = 2004;
287
+ PATIENT_PORTAL__SEND_CONTACT_VERIFICATION = 2013;
257
288
 
258
289
  PATIENT_PORTAL__APPOINTMENTS__SLOTS__POST_SEARCH_RESULTS = 2005;
259
290
  PATIENT_PORTAL__APPOINTMENTS__FORM_APPOINTMENT_TYPES__PRE_SEARCH_RESULTS = 2006;
@@ -264,10 +295,22 @@ enum EffectType {
264
295
  PATIENT_PORTAL__APPOINTMENTS__FORM_PROVIDERS__POST_SEARCH_RESULTS = 2011;
265
296
  PATIENT_PORTAL__APPLICATION_CONFIGURATION = 2012;
266
297
 
298
+ ADD_APPOINTMENT_LABEL = 2015;
299
+ REMOVE_APPOINTMENT_LABEL = 2016;
300
+
267
301
  ADD_BILLING_LINE_ITEM = 2030;
268
302
  UPDATE_BILLING_LINE_ITEM = 2031;
269
303
  REMOVE_BILLING_LINE_ITEM = 2032;
270
304
 
305
+ POST_CLAIM_PAYMENT = 2040;
306
+ POST_CLAIMS_REMIT = 2041;
307
+
308
+ MOVE_CLAIM_TO_QUEUE = 2060;
309
+ ADD_CLAIM_LABEL = 2050;
310
+ REMOVE_CLAIM_LABEL = 2051;
311
+
312
+ UPDATE_CLAIM_LINE_ITEM = 2080;
313
+
271
314
  SHOW_PATIENT_PORTAL_MENU_ITEMS = 2100;
272
315
  PORTAL_WIDGET = 2101;
273
316
 
@@ -282,13 +325,22 @@ enum EffectType {
282
325
 
283
326
  CREATE_NOTE = 6000;
284
327
  UPDATE_NOTE = 6013;
328
+ PUSH_NOTE_CHARGES = 5500;
329
+ FAX_NOTE = 6019;
330
+ LOCK_NOTE = 6025;
331
+ UNLOCK_NOTE = 6026;
332
+ SIGN_NOTE = 6027;
333
+ CHECK_IN_NOTE = 6028;
334
+ NO_SHOW_NOTE = 6029;
285
335
 
286
336
  CREATE_APPOINTMENT = 6001;
287
337
  UPDATE_APPOINTMENT = 6014;
338
+ RESCHEDULE_APPOINTMENT = 6022;
288
339
  CANCEL_APPOINTMENT = 6015;
289
340
  CREATE_SCHEDULE_EVENT = 6002;
290
341
  UPDATE_SCHEDULE_EVENT = 6016;
291
342
  DELETE_SCHEDULE_EVENT = 6017;
343
+ RESCHEDULE_SCHEDULE_EVENT = 6023;
292
344
 
293
345
  CREATE_PATIENT = 6003;
294
346
  UPDATE_PATIENT = 6008;
@@ -305,6 +357,9 @@ enum EffectType {
305
357
  CREATE_COMPOUND_MEDICATION = 6020;
306
358
  UPDATE_COMPOUND_MEDICATION = 6021;
307
359
 
360
+ CREATE_OBSERVATION = 6031;
361
+ UPDATE_OBSERVATION = 6032;
362
+
308
363
  PATIENT_CHART__GROUP_ITEMS = 6030;
309
364
 
310
365
  APPOINTMENT__FORM__PROVIDERS__PRE_SEARCH_RESULTS = 6040;
@@ -323,6 +378,8 @@ enum EffectType {
323
378
 
324
379
  UPSERT_APPOINTMENT_METADATA = 6052;
325
380
 
381
+ APPOINTMENT__SLOTS__POST_SEARCH_RESULTS = 6053;
382
+
326
383
  SHOW_PANEL_SECTIONS = 6100;
327
384
 
328
385
  REDIRECT_CONTEXT = 6200;
@@ -336,8 +393,14 @@ enum EffectType {
336
393
 
337
394
  GENERATE_FULL_CHART_PDF = 6101;
338
395
 
396
+ BATCH_ORIGINATE_COMMANDS = 6024;
397
+
339
398
  CALENDAR__CREATE = 8001;
340
399
  CALENDAR__EVENT__CREATE = 8002;
400
+ CALENDAR__EVENT__UPDATE = 8003;
401
+ CALENDAR__EVENT__DELETE = 8004;
402
+
403
+ ORIGINATE_CUSTOM_COMMAND_COMMAND = 8005;
341
404
  }
342
405
 
343
406
  message Effect {
@@ -346,6 +409,8 @@ message Effect {
346
409
  string plugin_name = 3;
347
410
  string classname = 4;
348
411
  string handler_name = 5;
412
+ string actor = 6;
413
+ string source = 7;
349
414
  //Oneof effect_payload {
350
415
  // ...
351
416
  //}