canvas 0.29.1__tar.gz → 0.31.0__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.

Potentially problematic release.


This version of canvas might be problematic. Click here for more details.

Files changed (364) hide show
  1. {canvas-0.29.1 → canvas-0.31.0}/PKG-INFO +1 -1
  2. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/validators/manifest_schema.py +1 -0
  3. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/protocol_card/protocol_card.py +3 -0
  4. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/base.py +3 -0
  5. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/simple_api/__init__.py +6 -0
  6. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/simple_api/security.py +65 -0
  7. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/tests/handlers/test_simple_api.py +56 -2
  8. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/user.py +1 -0
  9. {canvas-0.29.1 → canvas-0.31.0}/logger/logger.py +7 -1
  10. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/plugin_runner.py +43 -27
  11. {canvas-0.29.1 → canvas-0.31.0}/pyproject.toml +1 -1
  12. {canvas-0.29.1 → canvas-0.31.0}/.gitignore +0 -0
  13. {canvas-0.29.1 → canvas-0.31.0}/README.md +0 -0
  14. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/__init__.py +0 -0
  15. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/__init__.py +0 -0
  16. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/auth/__init__.py +0 -0
  17. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/auth/tests.py +0 -0
  18. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/auth/utils.py +0 -0
  19. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/__init__.py +0 -0
  20. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/emit.py +0 -0
  21. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_CREATED.ndjson +0 -0
  22. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_UPDATED.ndjson +0 -0
  23. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CANCELED.ndjson +0 -0
  24. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CHECKED_IN.ndjson +0 -0
  25. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CREATED.ndjson +0 -0
  26. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_NO_SHOWED.ndjson +0 -0
  27. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESCHEDULED.ndjson +0 -0
  28. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESTORED.ndjson +0 -0
  29. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_UPDATED.ndjson +0 -0
  30. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__CONDITION_SELECTED.ndjson +0 -0
  31. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_COMMIT.ndjson +0 -0
  32. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_ORIGINATE.ndjson +0 -0
  33. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_UPDATE.ndjson +0 -0
  34. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_COMMIT.ndjson +0 -0
  35. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  36. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_UPDATE.ndjson +0 -0
  37. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_CREATED.ndjson +0 -0
  38. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_UPDATED.ndjson +0 -0
  39. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_ASSESSED.ndjson +0 -0
  40. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_CREATED.ndjson +0 -0
  41. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_UPDATED.ndjson +0 -0
  42. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/CRON.ndjson +0 -0
  43. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_CREATED.ndjson +0 -0
  44. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_UPDATED.ndjson +0 -0
  45. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_CREATED.ndjson +0 -0
  46. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_CREATED.ndjson +0 -0
  47. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_UPDATED.ndjson +0 -0
  48. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_UPDATED.ndjson +0 -0
  49. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/INTERVIEW_CREATED.ndjson +0 -0
  50. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/INTERVIEW_UPDATED.ndjson +0 -0
  51. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_CREATED.ndjson +0 -0
  52. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_UPDATED.ndjson +0 -0
  53. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_CREATED.ndjson +0 -0
  54. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_UPDATED.ndjson +0 -0
  55. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_COMMIT.ndjson +0 -0
  56. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_ORIGINATE.ndjson +0 -0
  57. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_UPDATE.ndjson +0 -0
  58. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_COMMIT.ndjson +0 -0
  59. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  60. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_UPDATE.ndjson +0 -0
  61. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT__MEDICATION__POST_SEARCH.ndjson +0 -0
  62. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/PATIENT_CREATED.ndjson +0 -0
  63. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/PATIENT_UPDATED.ndjson +0 -0
  64. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__POST_ORIGINATE.ndjson +0 -0
  65. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  66. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_COMMIT.ndjson +0 -0
  67. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_ORIGINATE.ndjson +0 -0
  68. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_UPDATE.ndjson +0 -0
  69. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_COMMIT.ndjson +0 -0
  70. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  71. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_UPDATE.ndjson +0 -0
  72. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE__QUESTIONNAIRE__POST_SEARCH.ndjson +0 -0
  73. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/SIMPLE_API_REQUEST.ndjson +0 -0
  74. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/TASK_COMMENT_CREATED.ndjson +0 -0
  75. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/TASK_CREATED.ndjson +0 -0
  76. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/TASK_UPDATED.ndjson +0 -0
  77. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_CREATED.ndjson +0 -0
  78. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_UPDATED.ndjson +0 -0
  79. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/logs/__init__.py +0 -0
  80. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/logs/logs.py +0 -0
  81. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/plugin/__init__.py +0 -0
  82. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/plugin/plugin.py +0 -0
  83. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/plugin/tests.py +0 -0
  84. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/run_plugins/__init__.py +0 -0
  85. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/apps/run_plugins/run_plugins.py +0 -0
  86. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/conftest.py +0 -0
  87. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/main.py +0 -0
  88. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/cookiecutter.json +0 -0
  89. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +0 -0
  90. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/README.md +0 -0
  91. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/__init__.py +0 -0
  92. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/my_application.py +0 -0
  93. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/assets/python-logo.png +0 -0
  94. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/default/cookiecutter.json +0 -0
  95. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +0 -0
  96. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/README.md +0 -0
  97. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/__init__.py +0 -0
  98. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/my_protocol.py +0 -0
  99. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/tests.py +0 -0
  100. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/__init__.py +0 -0
  101. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/context/__init__.py +0 -0
  102. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/context/context.py +0 -0
  103. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/context/tests.py +0 -0
  104. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/print/__init__.py +0 -0
  105. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/print/print.py +0 -0
  106. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/print/tests.py +0 -0
  107. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/urls/__init__.py +0 -0
  108. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/urls/tests.py +0 -0
  109. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/urls/urls.py +0 -0
  110. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/validators/__init__.py +0 -0
  111. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/validators/tests.py +0 -0
  112. {canvas-0.29.1 → canvas-0.31.0}/canvas_cli/utils/validators/validators.py +0 -0
  113. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/effects_pb2.py +0 -0
  114. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/effects_pb2.pyi +0 -0
  115. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/effects_pb2_grpc.py +0 -0
  116. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/events_pb2.py +0 -0
  117. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/events_pb2.pyi +0 -0
  118. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/events_pb2_grpc.py +0 -0
  119. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/plugins_pb2.py +0 -0
  120. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/plugins_pb2.pyi +0 -0
  121. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/messages/plugins_pb2_grpc.py +0 -0
  122. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/services/plugin_runner_pb2.py +0 -0
  123. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/services/plugin_runner_pb2.pyi +0 -0
  124. {canvas-0.29.1 → canvas-0.31.0}/canvas_generated/services/plugin_runner_pb2_grpc.py +0 -0
  125. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/__init__.py +0 -0
  126. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/base.py +0 -0
  127. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/__init__.py +0 -0
  128. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/base.py +0 -0
  129. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/__init__.py +0 -0
  130. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/adjust_prescription.py +0 -0
  131. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/allergy.py +0 -0
  132. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/assess.py +0 -0
  133. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/close_goal.py +0 -0
  134. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/diagnose.py +0 -0
  135. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/exam.py +0 -0
  136. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/family_history.py +0 -0
  137. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/follow_up.py +0 -0
  138. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/goal.py +0 -0
  139. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/history_present_illness.py +0 -0
  140. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/imaging_order.py +0 -0
  141. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/instruct.py +0 -0
  142. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/lab_order.py +0 -0
  143. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/medical_history.py +0 -0
  144. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/medication_statement.py +0 -0
  145. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/past_surgical_history.py +0 -0
  146. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/perform.py +0 -0
  147. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/plan.py +0 -0
  148. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/prescribe.py +0 -0
  149. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/questionnaire/__init__.py +0 -0
  150. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/questionnaire/question.py +0 -0
  151. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/reason_for_visit.py +0 -0
  152. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/refer.py +0 -0
  153. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/refill.py +0 -0
  154. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/remove_allergy.py +0 -0
  155. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/resolve_condition.py +0 -0
  156. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/review_of_systems.py +0 -0
  157. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/stop_medication.py +0 -0
  158. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/structured_assessment.py +0 -0
  159. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/task.py +0 -0
  160. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/update_diagnosis.py +0 -0
  161. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/update_goal.py +0 -0
  162. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/commands/vitals.py +0 -0
  163. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/constants.py +0 -0
  164. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/protocol/__init__.py +0 -0
  165. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/protocol/tests.py +0 -0
  166. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/schema/__init__.py +0 -0
  167. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/schema/tests.py +0 -0
  168. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/test_base_command.py +0 -0
  169. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/test_utils.py +0 -0
  170. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/unit/__init__.py +0 -0
  171. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/commands/tests/unit/tests.py +0 -0
  172. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/__init__.py +0 -0
  173. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/banner_alert/__init__.py +0 -0
  174. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/banner_alert/add_banner_alert.py +0 -0
  175. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/banner_alert/remove_banner_alert.py +0 -0
  176. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/banner_alert/tests.py +0 -0
  177. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/base.py +0 -0
  178. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/billing_line_item/__init__.py +0 -0
  179. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/billing_line_item/add_billing_line_item.py +0 -0
  180. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +0 -0
  181. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/billing_line_item/update_billing_line_item.py +0 -0
  182. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/launch_modal.py +0 -0
  183. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_chart_summary_configuration.py +0 -0
  184. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_portal/__init__.py +0 -0
  185. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_portal/application_configuration.py +0 -0
  186. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_portal/form_result.py +0 -0
  187. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_portal_menu_configuration.py +0 -0
  188. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/patient_profile_configuration.py +0 -0
  189. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/protocol_card/__init__.py +0 -0
  190. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/protocol_card/tests.py +0 -0
  191. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/questionnaire_result.py +0 -0
  192. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/show_button.py +0 -0
  193. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/simple_api.py +0 -0
  194. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/surescripts/__init__.py +0 -0
  195. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/surescripts/surescripts_messages.py +0 -0
  196. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/task/__init__.py +0 -0
  197. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/task/task.py +0 -0
  198. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/widgets/__init__.py +0 -0
  199. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/effects/widgets/portal_widget.py +0 -0
  200. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/events/__init__.py +0 -0
  201. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/events/base.py +0 -0
  202. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/__init__.py +0 -0
  203. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/action_button.py +0 -0
  204. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/application.py +0 -0
  205. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/cron_task.py +0 -0
  206. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/simple_api/api.py +0 -0
  207. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/simple_api/exceptions.py +0 -0
  208. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/handlers/simple_api/tools.py +0 -0
  209. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/protocols/__init__.py +0 -0
  210. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/protocols/base.py +0 -0
  211. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/protocols/clinical_quality_measure.py +0 -0
  212. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/protocols/timeframe.py +0 -0
  213. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/questionnaires/__init__.py +0 -0
  214. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/questionnaires/tests/__init__.py +0 -0
  215. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/questionnaires/tests/test_utils.py +0 -0
  216. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/questionnaires/utils.py +0 -0
  217. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/templates/__init__.py +0 -0
  218. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/templates/tests/__init__.py +0 -0
  219. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/templates/tests/test_utils.py +0 -0
  220. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/templates/utils.py +0 -0
  221. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/tests/__init__.py +0 -0
  222. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/tests/handlers/__init__.py +0 -0
  223. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/utils/__init__.py +0 -0
  224. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/utils/http.py +0 -0
  225. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/utils/plugins.py +0 -0
  226. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/utils/stats.py +0 -0
  227. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/utils/tests.py +0 -0
  228. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/__init__.py +0 -0
  229. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/apps.py +0 -0
  230. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/__init__.py +0 -0
  231. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/allergy_intolerance.py +0 -0
  232. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/appointment.py +0 -0
  233. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/assessment.py +0 -0
  234. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/banner_alert.py +0 -0
  235. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/base.py +0 -0
  236. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/billing.py +0 -0
  237. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/care_team.py +0 -0
  238. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/command.py +0 -0
  239. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/common.py +0 -0
  240. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/condition.py +0 -0
  241. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/coverage.py +0 -0
  242. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/detected_issue.py +0 -0
  243. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/device.py +0 -0
  244. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/imaging.py +0 -0
  245. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/lab.py +0 -0
  246. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/medication.py +0 -0
  247. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/note.py +0 -0
  248. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/observation.py +0 -0
  249. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/organization.py +0 -0
  250. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/patient.py +0 -0
  251. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/practicelocation.py +0 -0
  252. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/protocol_override.py +0 -0
  253. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/questionnaire.py +0 -0
  254. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/reason_for_visit.py +0 -0
  255. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/staff.py +0 -0
  256. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/task.py +0 -0
  257. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/data/team.py +0 -0
  258. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/v1/models.py +0 -0
  259. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/__init__.py +0 -0
  260. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/custom.py +0 -0
  261. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/hcc2018.py +0 -0
  262. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/tests/test_value_sets.py +0 -0
  263. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/__init__.py +0 -0
  264. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/adverse_event.py +0 -0
  265. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/allergy.py +0 -0
  266. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/assessment.py +0 -0
  267. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/communication.py +0 -0
  268. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/condition.py +0 -0
  269. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/device.py +0 -0
  270. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/diagnostic_study.py +0 -0
  271. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/encounter.py +0 -0
  272. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/immunization.py +0 -0
  273. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/individual_characteristic.py +0 -0
  274. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/intervention.py +0 -0
  275. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/laboratory_test.py +0 -0
  276. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/medication.py +0 -0
  277. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/physical_exam.py +0 -0
  278. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/procedure.py +0 -0
  279. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/v2022/symptom.py +0 -0
  280. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/value_set/value_set.py +0 -0
  281. {canvas-0.29.1 → canvas-0.31.0}/canvas_sdk/views/__init__.py +0 -0
  282. {canvas-0.29.1 → canvas-0.31.0}/logger/__init__.py +0 -0
  283. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/__init__.py +0 -0
  284. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/authentication.py +0 -0
  285. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/aws_headers.py +0 -0
  286. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/exceptions.py +0 -0
  287. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/installation.py +0 -0
  288. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/sandbox.py +0 -0
  289. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/__init__.py +0 -0
  290. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/example_plugin/CANVAS_MANIFEST.json +0 -0
  291. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/example_plugin/README.md +0 -0
  292. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/example_plugin/__init__.py +0 -0
  293. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/example_plugin/protocols/__init__.py +0 -0
  294. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/example_plugin/protocols/my_protocol.py +0 -0
  295. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/CANVAS_MANIFEST.json +0 -0
  296. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/README.md +0 -0
  297. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/__init__.py +0 -0
  298. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/my_protocol.py +0 -0
  299. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/__init__.py +0 -0
  300. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/base.py +0 -0
  301. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/__init__.py +0 -0
  302. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/base.py +0 -0
  303. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_load_questionnaire/CANVAS_MANIFEST.json +0 -0
  304. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_load_questionnaire/README.md +0 -0
  305. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/__init__.py +0 -0
  306. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/my_protocol.py +0 -0
  307. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_load_questionnaire/questionnaires/example_questionnaire.yml +0 -0
  308. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/CANVAS_MANIFEST.json +0 -0
  309. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/README.md +0 -0
  310. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/__init__.py +0 -0
  311. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/base.py +0 -0
  312. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/__init__.py +0 -0
  313. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/my_protocol.py +0 -0
  314. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/CANVAS_MANIFEST.json +0 -0
  315. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/README.md +0 -0
  316. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/__init__.py +0 -0
  317. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/base.py +0 -0
  318. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/__init__.py +0 -0
  319. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/my_protocol.py +0 -0
  320. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/CANVAS_MANIFEST.json +0 -0
  321. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/README.md +0 -0
  322. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/__init__.py +0 -0
  323. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/base.py +0 -0
  324. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/__init__.py +0 -0
  325. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/my_protocol.py +0 -0
  326. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/CANVAS_MANIFEST.json +0 -0
  327. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/README.md +0 -0
  328. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/__init__.py +0 -0
  329. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/base.py +0 -0
  330. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/__init__.py +0 -0
  331. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/my_protocol.py +0 -0
  332. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/CANVAS_MANIFEST.json +0 -0
  333. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/README.md +0 -0
  334. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/__init__.py +0 -0
  335. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/base.py +0 -0
  336. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/__init__.py +0 -0
  337. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/my_protocol.py +0 -0
  338. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/CANVAS_MANIFEST.json +0 -0
  339. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/README.md +0 -0
  340. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/__init__.py +0 -0
  341. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/base.py +0 -0
  342. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/__init__.py +0 -0
  343. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/my_protocol.py +0 -0
  344. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_render_template/CANVAS_MANIFEST.json +0 -0
  345. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_render_template/README.md +0 -0
  346. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_render_template/protocols/__init__.py +0 -0
  347. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_render_template/protocols/my_protocol.py +0 -0
  348. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_render_template/templates/template.html +0 -0
  349. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_simple_api/CANVAS_MANIFEST.json +0 -0
  350. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_simple_api/README.md +0 -0
  351. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_simple_api/__init__.py +0 -0
  352. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/__init__.py +0 -0
  353. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/my_protocol.py +0 -0
  354. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/test_application.py +0 -0
  355. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/test_plugin_installer.py +0 -0
  356. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/test_plugin_runner.py +0 -0
  357. {canvas-0.29.1 → canvas-0.31.0}/plugin_runner/tests/test_sandbox.py +0 -0
  358. {canvas-0.29.1 → canvas-0.31.0}/protobufs/canvas_generated/messages/effects.proto +0 -0
  359. {canvas-0.29.1 → canvas-0.31.0}/protobufs/canvas_generated/messages/events.proto +0 -0
  360. {canvas-0.29.1 → canvas-0.31.0}/protobufs/canvas_generated/messages/plugins.proto +0 -0
  361. {canvas-0.29.1 → canvas-0.31.0}/protobufs/canvas_generated/services/plugin_runner.proto +0 -0
  362. {canvas-0.29.1 → canvas-0.31.0}/pubsub/__init__.py +0 -0
  363. {canvas-0.29.1 → canvas-0.31.0}/pubsub/pubsub.py +0 -0
  364. {canvas-0.29.1 → canvas-0.31.0}/settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: canvas
3
- Version: 0.29.1
3
+ Version: 0.31.0
4
4
  Summary: SDK to customize event-driven actions in your Canvas instance
5
5
  Author-email: Canvas Team <engineering@canvasmedical.com>
6
6
  License-Expression: MIT
@@ -81,6 +81,7 @@ manifest_schema = {
81
81
  "SCRIPTS",
82
82
  "ALLOW_SAME_ORIGIN",
83
83
  "MICROPHONE",
84
+ "CAMERA",
84
85
  ],
85
86
  },
86
87
  },
@@ -39,6 +39,9 @@ class ProtocolCard(_BaseEffect):
39
39
  class Status(Enum):
40
40
  DUE = "due"
41
41
  SATISFIED = "satisfied"
42
+ NOT_APPLICABLE = "not_applicable"
43
+ PENDING = "pending"
44
+ NOT_RELEVANT = "not_relevant"
42
45
 
43
46
  class Meta:
44
47
  effect_type = EffectType.ADD_OR_UPDATE_PROTOCOL_CARD
@@ -13,6 +13,7 @@ version = importlib.metadata.version("canvas")
13
13
  class BaseHandler(ABC):
14
14
  """The class that all handlers inherit from."""
15
15
 
16
+ environment: dict[str, Any]
16
17
  secrets: dict[str, Any]
17
18
  event: Event
18
19
 
@@ -20,9 +21,11 @@ class BaseHandler(ABC):
20
21
  self,
21
22
  event: Event,
22
23
  secrets: dict[str, Any] | None = None,
24
+ environment: dict[str, Any] | None = None,
23
25
  ) -> None:
24
26
  self.event = event
25
27
  self.secrets = secrets or {}
28
+ self.environment = environment or {}
26
29
 
27
30
  @property
28
31
  @deprecation.deprecated(
@@ -7,6 +7,9 @@ from .security import (
7
7
  BasicCredentials,
8
8
  BearerCredentials,
9
9
  Credentials,
10
+ PatientSessionAuthMixin,
11
+ SessionCredentials,
12
+ StaffSessionAuthMixin,
10
13
  )
11
14
 
12
15
  __all__ = [
@@ -17,6 +20,9 @@ __all__ = [
17
20
  "BasicCredentials",
18
21
  "BearerCredentials",
19
22
  "Credentials",
23
+ "PatientSessionAuthMixin",
24
+ "SessionCredentials",
20
25
  "SimpleAPI",
21
26
  "SimpleAPIRoute",
27
+ "StaffSessionAuthMixin",
22
28
  ]
@@ -114,6 +114,39 @@ class APIKeyCredentials(Credentials):
114
114
  self.key = key
115
115
 
116
116
 
117
+ class SessionCredentials(Credentials):
118
+ """
119
+ Session credentials class.
120
+
121
+ Looks for headers set by Canvas with information about the logged in user based on browser
122
+ cookies and session information in the Canvas database. These headers are removed if received by
123
+ the client and intentionally set by Canvas only if there is a valid session from an active user.
124
+
125
+ One must look at the type of user in order to understand what the id refers to – a patient or a
126
+ staff member.
127
+
128
+ If a SimpleAPI handler is protected by SessionCredentials, the non-presence of these headers
129
+ results in an unauthorized response. Users of SessionCredentials will likely wish to further
130
+ restrict access based on the type of user (patient or staff) and perhaps based on the roles
131
+ associated with the user. This logic is the concern of the implementer of the handler's
132
+ authenticate method.
133
+ """
134
+
135
+ def __init__(self, request: "Request") -> None:
136
+ super().__init__(request)
137
+
138
+ if (
139
+ "canvas-logged-in-user-type" not in request.headers
140
+ or "canvas-logged-in-user-id" not in request.headers
141
+ ):
142
+ raise InvalidCredentialsError
143
+
144
+ self.logged_in_user = {
145
+ "id": request.headers.get("canvas-logged-in-user-id"),
146
+ "type": request.headers.get("canvas-logged-in-user-type"),
147
+ }
148
+
149
+
117
150
  class AuthSchemeMixin(Protocol):
118
151
  """Protocol for authentication scheme mixins."""
119
152
 
@@ -182,3 +215,35 @@ class APIKeyAuthMixin(AuthSchemeMixin):
182
215
  raise InvalidCredentialsError
183
216
 
184
217
  return True
218
+
219
+
220
+ class StaffSessionAuthMixin(AuthSchemeMixin):
221
+ """
222
+ Staff Session authentication scheme mixin.
223
+
224
+ Provides an implementation of the authenticate method that ensures only logged in staff members
225
+ can access the urls provided by this handler. It only cares that they are a staff, with no
226
+ regard to roles or any other permissioning schemes.
227
+ """
228
+
229
+ def authenticate(self, credentials: SessionCredentials) -> bool: # type: ignore[override]
230
+ """Authenticate the request."""
231
+ if credentials.logged_in_user["type"] != "Staff":
232
+ raise InvalidCredentialsError
233
+ return True
234
+
235
+
236
+ class PatientSessionAuthMixin(AuthSchemeMixin):
237
+ """
238
+ Patient Session authentication scheme mixin.
239
+
240
+ Provides an implementation of the authenticate method that ensures only logged in patients can
241
+ access the urls provided by this handler. It only cares that they are a patient, with no regard
242
+ any other information.
243
+ """
244
+
245
+ def authenticate(self, credentials: SessionCredentials) -> bool: # type: ignore[override]
246
+ """Authenticate the request."""
247
+ if credentials.logged_in_user["type"] != "Patient":
248
+ raise InvalidCredentialsError
249
+ return True
@@ -37,6 +37,9 @@ from canvas_sdk.handlers.simple_api.security import (
37
37
  BasicCredentials,
38
38
  BearerCredentials,
39
39
  Credentials,
40
+ PatientSessionAuthMixin,
41
+ SessionCredentials,
42
+ StaffSessionAuthMixin,
40
43
  )
41
44
  from canvas_sdk.handlers.simple_api.tools import (
42
45
  CaseInsensitiveMultiDict,
@@ -890,6 +893,13 @@ def custom_headers(api_key: str, app_key: str) -> dict[str, str]:
890
893
  return {"API-Key": api_key, "App-Key": app_key}
891
894
 
892
895
 
896
+ def session_headers(id: str, type: str) -> dict[str, str]:
897
+ """
898
+ Given an id and a type, return headers that include the expected session based auth headers.
899
+ """
900
+ return {"canvas-logged-in-user-type": type, "canvas-logged-in-user-id": id}
901
+
902
+
893
903
  USERNAME = uuid4().hex
894
904
  PASSWORD = uuid4().hex
895
905
  TOKEN = uuid4().hex
@@ -915,6 +925,11 @@ APP_KEY = uuid4().hex
915
925
  lambda _, credentials: credentials.key == API_KEY,
916
926
  api_key_headers(API_KEY),
917
927
  ),
928
+ (
929
+ SessionCredentials,
930
+ lambda _, credentials: credentials.logged_in_user["type"] == "Staff",
931
+ session_headers("abc123", "Staff"),
932
+ ),
918
933
  (
919
934
  Credentials,
920
935
  lambda request, _: request.headers.get("API-Key") == API_KEY
@@ -922,7 +937,7 @@ APP_KEY = uuid4().hex
922
937
  custom_headers(API_KEY, APP_KEY),
923
938
  ),
924
939
  ],
925
- ids=["basic", "bearer", "API key", "custom"],
940
+ ids=["basic", "bearer", "API key", "custom", "session"],
926
941
  )
927
942
  def authenticated_route(request: SubRequest) -> SimpleNamespace:
928
943
  """
@@ -998,8 +1013,9 @@ def test_authentication_failure(
998
1013
  (BearerCredentials, bearer_headers(TOKEN)),
999
1014
  (APIKeyCredentials, api_key_headers(API_KEY)),
1000
1015
  (Credentials, custom_headers(API_KEY, APP_KEY)),
1016
+ (SessionCredentials, session_headers("abc123", "Patient")),
1001
1017
  ],
1002
- ids=["basic", "bearer", "API key", "custom"],
1018
+ ids=["basic", "bearer", "API key", "custom", "session"],
1003
1019
  )
1004
1020
  def test_authentication_exception(
1005
1021
  credentials_cls: type[Credentials], headers: Mapping[str, str]
@@ -1079,6 +1095,40 @@ def test_authentication_exception(
1079
1095
  ).apply()
1080
1096
  ],
1081
1097
  ),
1098
+ (
1099
+ StaffSessionAuthMixin,
1100
+ {},
1101
+ session_headers("abc123", "Staff"),
1102
+ [Effect(type=EffectType.CREATE_TASK, payload="create task")],
1103
+ ),
1104
+ (
1105
+ StaffSessionAuthMixin,
1106
+ {},
1107
+ session_headers("abc123", "Patient"),
1108
+ [
1109
+ JSONResponse(
1110
+ content={"error": "Provided credentials are invalid"},
1111
+ status_code=HTTPStatus.UNAUTHORIZED,
1112
+ ).apply()
1113
+ ],
1114
+ ),
1115
+ (
1116
+ PatientSessionAuthMixin,
1117
+ {},
1118
+ session_headers("abc123", "Patient"),
1119
+ [Effect(type=EffectType.CREATE_TASK, payload="create task")],
1120
+ ),
1121
+ (
1122
+ PatientSessionAuthMixin,
1123
+ {},
1124
+ session_headers("abc123", "Staff"),
1125
+ [
1126
+ JSONResponse(
1127
+ content={"error": "Provided credentials are invalid"},
1128
+ status_code=HTTPStatus.UNAUTHORIZED,
1129
+ ).apply()
1130
+ ],
1131
+ ),
1082
1132
  ],
1083
1133
  ids=[
1084
1134
  "basic valid",
@@ -1087,6 +1137,10 @@ def test_authentication_exception(
1087
1137
  "API key valid",
1088
1138
  "API key invalid",
1089
1139
  "API key missing secret",
1140
+ "Staff session valid",
1141
+ "Staff session invalid",
1142
+ "Patient session valid",
1143
+ "Patient session invalid",
1090
1144
  ],
1091
1145
  )
1092
1146
  def test_authentication_mixins(
@@ -9,3 +9,4 @@ class CanvasUser(models.Model):
9
9
  db_table = "canvas_sdk_data_api_auth_user_001"
10
10
 
11
11
  dbid = models.BigIntegerField(db_column="dbid", primary_key=True)
12
+ email = models.CharField()
@@ -2,6 +2,8 @@ import logging
2
2
  import os
3
3
  from typing import Any
4
4
 
5
+ import redis
6
+
5
7
  from pubsub.pubsub import Publisher
6
8
 
7
9
 
@@ -15,7 +17,11 @@ class PubSubLogHandler(logging.Handler):
15
17
  def emit(self, record: Any) -> None:
16
18
  """Publishes the log message to the pub/sub channel."""
17
19
  message = self.format(record)
18
- self.publisher.publish(message)
20
+
21
+ try:
22
+ self.publisher.publish(message)
23
+ except redis.ConnectionError as e:
24
+ print(f"PubSubLogHandler: failed to log message due to redis error: {e}")
19
25
 
20
26
 
21
27
  class PluginLogger:
@@ -34,6 +34,7 @@ from plugin_runner.installation import install_plugins
34
34
  from plugin_runner.sandbox import Sandbox
35
35
  from settings import (
36
36
  CHANNEL_NAME,
37
+ CUSTOMER_IDENTIFIER,
37
38
  IS_TESTING,
38
39
  MANIFEST_FILE_NAME,
39
40
  PLUGIN_DIRECTORY,
@@ -49,6 +50,11 @@ sys.path.append(PLUGIN_DIRECTORY)
49
50
  # TODO: create typings here for the subkeys
50
51
  LOADED_PLUGINS: dict = {}
51
52
 
53
+ # a global dictionary of values made available to all plugins
54
+ ENVIRONMENT: dict = {
55
+ "CUSTOMER_IDENTIFIER": CUSTOMER_IDENTIFIER,
56
+ }
57
+
52
58
  # a global dictionary of events to handler class names
53
59
  EVENT_HANDLER_MAP: dict[str, list] = defaultdict(list)
54
60
 
@@ -174,7 +180,7 @@ class PluginRunner(PluginRunnerServicer):
174
180
  )
175
181
 
176
182
  try:
177
- handler = handler_class(event, secrets)
183
+ handler = handler_class(event, secrets, ENVIRONMENT)
178
184
 
179
185
  if not handler.accept_event():
180
186
  continue
@@ -267,38 +273,48 @@ async def synchronize_plugins(run_once: bool = False) -> None:
267
273
  log.info(f'synchronize_plugins: listening for messages on pubsub channel "{CHANNEL_NAME}"')
268
274
 
269
275
  _, pubsub = get_client()
276
+
270
277
  await pubsub.psubscribe(CHANNEL_NAME)
271
278
 
272
279
  while True:
273
- message = await pubsub.get_message(ignore_subscribe_messages=True, timeout=None)
280
+ message = await pubsub.get_message(ignore_subscribe_messages=True, timeout=5.0)
274
281
 
275
- if message is not None:
276
- log.info(f'synchronize_plugins: received message from pubsub channel "{CHANNEL_NAME}"')
282
+ if message is None:
283
+ continue
277
284
 
278
- message_type = message.get("type", "")
285
+ log.info(f'synchronize_plugins: received message from pubsub channel "{CHANNEL_NAME}"')
279
286
 
280
- if message_type != "pmessage":
281
- continue
287
+ message_type = message.get("type", "")
282
288
 
283
- data = pickle.loads(message.get("data", pickle.dumps({})))
289
+ if message_type != "pmessage":
290
+ continue
284
291
 
285
- if "action" not in data:
286
- continue
292
+ data = pickle.loads(message.get("data", pickle.dumps({})))
293
+
294
+ if "action" not in data:
295
+ continue
296
+
297
+ if data["action"] == "reload":
298
+ log.info("synchronize_plugins: installing and reloading plugins for action=reload")
299
+
300
+ try:
301
+ install_plugins()
302
+ except Exception as e:
303
+ # TODO capture_exception when Sentry is installed
304
+ log.error(f"synchronize_plugins: install_plugins failed: {e}")
305
+
306
+ try:
307
+ load_plugins()
308
+ except Exception as e:
309
+ # TODO capture_exception when Sentry is installed
310
+ log.error(f"synchronize_plugins: load_plugins failed: {e}")
287
311
 
288
- if data["action"] == "reload":
289
- log.info("synchronize_plugins: installing and reloading plugins for action=reload")
312
+ await pubsub.check_health()
290
313
 
291
- try:
292
- install_plugins()
293
- except Exception as e:
294
- # TODO capture_exception when Sentry is installed
295
- log.error(f"synchronize_plugins: install_plugins failed: {e}")
314
+ if not pubsub.connection.is_connected: # type: ignore
315
+ log.info("synchronize_plugins: reconnecting to Redis")
316
+ await pubsub.connection.connect() # type: ignore
296
317
 
297
- try:
298
- load_plugins()
299
- except Exception as e:
300
- # TODO capture_exception when Sentry is installed
301
- log.error(f"synchronize_plugins: load_plugins failed: {e}")
302
318
  if run_once:
303
319
  break
304
320
 
@@ -307,13 +323,13 @@ async def synchronize_plugins_and_report_errors() -> None:
307
323
  """
308
324
  Run synchronize_plugins() in perpetuity and report any encountered errors.
309
325
  """
310
- log.info("Starting synchronize_plugins loop...")
326
+ log.info("synchronize_plugins: starting loop...")
311
327
 
312
328
  while True:
313
329
  try:
314
330
  await synchronize_plugins()
315
331
  except Exception as e:
316
- log.error(f"synchronize_plugins error: {e}")
332
+ log.error(f"synchronize_plugins: error: {e}")
317
333
 
318
334
  # don't crush redis if we're retrying in a tight loop
319
335
  await asyncio.sleep(0.5)
@@ -580,13 +596,13 @@ def run_server(specified_plugin_paths: list[str] | None = None) -> None:
580
596
  asyncio.set_event_loop(loop)
581
597
 
582
598
  try:
583
- coros = [serve(specified_plugin_paths)]
599
+ coroutines = [serve(specified_plugin_paths)]
584
600
 
585
601
  # Only start the synchronizer if the plugin runner was not started from the CLI
586
602
  if specified_plugin_paths is None:
587
- coros.append(synchronize_plugins_and_report_errors())
603
+ coroutines.append(synchronize_plugins_and_report_errors())
588
604
 
589
- loop.run_until_complete(asyncio.gather(*coros))
605
+ loop.run_until_complete(asyncio.gather(*coroutines))
590
606
  except KeyboardInterrupt:
591
607
  pass
592
608
  finally:
@@ -50,7 +50,7 @@ license = "MIT"
50
50
  name = "canvas"
51
51
  readme = "README.md"
52
52
  requires-python = ">=3.11,<3.13"
53
- version = "0.29.1"
53
+ version = "0.31.0"
54
54
 
55
55
  [project.scripts]
56
56
  canvas = "canvas_cli.main:app"
File without changes
File without changes
File without changes
File without changes
File without changes