canvas 0.77.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.
Files changed (371) hide show
  1. canvas-0.77.0/.gitignore +20 -0
  2. canvas-0.77.0/PKG-INFO +225 -0
  3. canvas-0.77.0/README.md +186 -0
  4. canvas-0.77.0/canvas_cli/__init__.py +0 -0
  5. canvas-0.77.0/canvas_cli/apps/__init__.py +0 -0
  6. canvas-0.77.0/canvas_cli/apps/auth/__init__.py +3 -0
  7. canvas-0.77.0/canvas_cli/apps/auth/storage.py +65 -0
  8. canvas-0.77.0/canvas_cli/apps/auth/utils.py +127 -0
  9. canvas-0.77.0/canvas_cli/apps/emit/__init__.py +3 -0
  10. canvas-0.77.0/canvas_cli/apps/emit/emit.py +66 -0
  11. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_CREATED.ndjson +1 -0
  12. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_UPDATED.ndjson +1 -0
  13. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CANCELED.ndjson +1 -0
  14. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CHECKED_IN.ndjson +1 -0
  15. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CREATED.ndjson +1 -0
  16. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_NO_SHOWED.ndjson +1 -0
  17. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESCHEDULED.ndjson +1 -0
  18. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESTORED.ndjson +1 -0
  19. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_UPDATED.ndjson +2 -0
  20. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__CONDITION_SELECTED.ndjson +1 -0
  21. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_COMMIT.ndjson +3 -0
  22. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_ORIGINATE.ndjson +4 -0
  23. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_UPDATE.ndjson +5 -0
  24. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_COMMIT.ndjson +3 -0
  25. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_ORIGINATE.ndjson +4 -0
  26. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_UPDATE.ndjson +5 -0
  27. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_CREATED.ndjson +3 -0
  28. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_UPDATED.ndjson +2 -0
  29. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_ASSESSED.ndjson +2 -0
  30. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_CREATED.ndjson +4 -0
  31. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_UPDATED.ndjson +5 -0
  32. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CRON.ndjson +3 -0
  33. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_CREATED.ndjson +3 -0
  34. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_UPDATED.ndjson +2 -0
  35. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_CREATED.ndjson +1 -0
  36. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_CREATED.ndjson +1 -0
  37. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_UPDATED.ndjson +1 -0
  38. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_UPDATED.ndjson +1 -0
  39. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/INTERVIEW_CREATED.ndjson +1 -0
  40. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/INTERVIEW_UPDATED.ndjson +1 -0
  41. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_CREATED.ndjson +1 -0
  42. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_UPDATED.ndjson +1 -0
  43. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_CREATED.ndjson +1 -0
  44. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_UPDATED.ndjson +1 -0
  45. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_COMMIT.ndjson +1 -0
  46. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_ORIGINATE.ndjson +1 -0
  47. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_UPDATE.ndjson +2 -0
  48. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_COMMIT.ndjson +1 -0
  49. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_ORIGINATE.ndjson +1 -0
  50. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_UPDATE.ndjson +2 -0
  51. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT__MEDICATION__POST_SEARCH.ndjson +2 -0
  52. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PATIENT_CREATED.ndjson +1 -0
  53. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PATIENT_UPDATED.ndjson +1 -0
  54. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__POST_ORIGINATE.ndjson +1 -0
  55. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__PRE_ORIGINATE.ndjson +1 -0
  56. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_COMMIT.ndjson +1 -0
  57. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_ORIGINATE.ndjson +1 -0
  58. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_UPDATE.ndjson +2 -0
  59. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_COMMIT.ndjson +1 -0
  60. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_ORIGINATE.ndjson +1 -0
  61. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_UPDATE.ndjson +2 -0
  62. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE__QUESTIONNAIRE__POST_SEARCH.ndjson +4 -0
  63. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/SIMPLE_API_REQUEST.ndjson +1 -0
  64. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_COMMENT_CREATED.ndjson +1 -0
  65. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_CREATED.ndjson +1 -0
  66. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_UPDATED.ndjson +1 -0
  67. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/UNKNOWN.ndjson +1 -0
  68. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_CREATED.ndjson +14 -0
  69. canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_UPDATED.ndjson +364 -0
  70. canvas-0.77.0/canvas_cli/apps/logs/__init__.py +3 -0
  71. canvas-0.77.0/canvas_cli/apps/logs/logs.py +65 -0
  72. canvas-0.77.0/canvas_cli/apps/plugin/__init__.py +23 -0
  73. canvas-0.77.0/canvas_cli/apps/plugin/plugin.py +619 -0
  74. canvas-0.77.0/canvas_cli/apps/run_plugins/__init__.py +3 -0
  75. canvas-0.77.0/canvas_cli/apps/run_plugins/run_plugins.py +102 -0
  76. canvas-0.77.0/canvas_cli/main.py +86 -0
  77. canvas-0.77.0/canvas_cli/templates/plugins/application/cookiecutter.json +4 -0
  78. canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +33 -0
  79. canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/README.md +11 -0
  80. canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/__init__.py +0 -0
  81. canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/my_application.py +15 -0
  82. canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/assets/python-logo.png +0 -0
  83. canvas-0.77.0/canvas_cli/templates/plugins/default/cookiecutter.json +5 -0
  84. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/pyproject.toml +16 -0
  85. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/__init__.py +0 -0
  86. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/test_models.py +63 -0
  87. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/CANVAS_MANIFEST.json +24 -0
  88. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/README.md +11 -0
  89. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/protocols/__init__.py +0 -0
  90. canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/protocols/my_protocol.py +55 -0
  91. canvas-0.77.0/canvas_cli/utils/__init__.py +0 -0
  92. canvas-0.77.0/canvas_cli/utils/context/__init__.py +3 -0
  93. canvas-0.77.0/canvas_cli/utils/context/context.py +150 -0
  94. canvas-0.77.0/canvas_cli/utils/print/__init__.py +3 -0
  95. canvas-0.77.0/canvas_cli/utils/print/print.py +46 -0
  96. canvas-0.77.0/canvas_cli/utils/urls/__init__.py +3 -0
  97. canvas-0.77.0/canvas_cli/utils/urls/urls.py +27 -0
  98. canvas-0.77.0/canvas_cli/utils/validators/__init__.py +3 -0
  99. canvas-0.77.0/canvas_cli/utils/validators/manifest_schema.py +157 -0
  100. canvas-0.77.0/canvas_cli/utils/validators/validators.py +40 -0
  101. canvas-0.77.0/canvas_generated/messages/effects_pb2.py +28 -0
  102. canvas-0.77.0/canvas_generated/messages/effects_pb2.pyi +591 -0
  103. canvas-0.77.0/canvas_generated/messages/effects_pb2_grpc.py +4 -0
  104. canvas-0.77.0/canvas_generated/messages/events_pb2.py +31 -0
  105. canvas-0.77.0/canvas_generated/messages/events_pb2.pyi +1895 -0
  106. canvas-0.77.0/canvas_generated/messages/events_pb2_grpc.py +4 -0
  107. canvas-0.77.0/canvas_generated/messages/plugins_pb2.py +36 -0
  108. canvas-0.77.0/canvas_generated/messages/plugins_pb2.pyi +39 -0
  109. canvas-0.77.0/canvas_generated/messages/plugins_pb2_grpc.py +4 -0
  110. canvas-0.77.0/canvas_generated/services/plugin_runner_pb2.py +28 -0
  111. canvas-0.77.0/canvas_generated/services/plugin_runner_pb2.pyi +6 -0
  112. canvas-0.77.0/canvas_generated/services/plugin_runner_pb2_grpc.py +166 -0
  113. canvas-0.77.0/canvas_sdk/__init__.py +12 -0
  114. canvas-0.77.0/canvas_sdk/base.py +109 -0
  115. canvas-0.77.0/canvas_sdk/caching/__init__.py +1 -0
  116. canvas-0.77.0/canvas_sdk/caching/base.py +127 -0
  117. canvas-0.77.0/canvas_sdk/caching/client.py +26 -0
  118. canvas-0.77.0/canvas_sdk/caching/exceptions.py +21 -0
  119. canvas-0.77.0/canvas_sdk/caching/plugins.py +23 -0
  120. canvas-0.77.0/canvas_sdk/caching/utils.py +28 -0
  121. canvas-0.77.0/canvas_sdk/commands/__init__.py +73 -0
  122. canvas-0.77.0/canvas_sdk/commands/base.py +203 -0
  123. canvas-0.77.0/canvas_sdk/commands/commands/__init__.py +1 -0
  124. canvas-0.77.0/canvas_sdk/commands/commands/adjust_prescription.py +21 -0
  125. canvas-0.77.0/canvas_sdk/commands/commands/allergy.py +45 -0
  126. canvas-0.77.0/canvas_sdk/commands/commands/assess.py +44 -0
  127. canvas-0.77.0/canvas_sdk/commands/commands/change_medication.py +58 -0
  128. canvas-0.77.0/canvas_sdk/commands/commands/chart_section_review.py +23 -0
  129. canvas-0.77.0/canvas_sdk/commands/commands/close_goal.py +16 -0
  130. canvas-0.77.0/canvas_sdk/commands/commands/diagnose.py +22 -0
  131. canvas-0.77.0/canvas_sdk/commands/commands/exam.py +12 -0
  132. canvas-0.77.0/canvas_sdk/commands/commands/family_history.py +31 -0
  133. canvas-0.77.0/canvas_sdk/commands/commands/follow_up.py +74 -0
  134. canvas-0.77.0/canvas_sdk/commands/commands/goal.py +39 -0
  135. canvas-0.77.0/canvas_sdk/commands/commands/history_present_illness.py +13 -0
  136. canvas-0.77.0/canvas_sdk/commands/commands/imaging_order.py +43 -0
  137. canvas-0.77.0/canvas_sdk/commands/commands/immunization_statement.py +72 -0
  138. canvas-0.77.0/canvas_sdk/commands/commands/instruct.py +31 -0
  139. canvas-0.77.0/canvas_sdk/commands/commands/lab_order.py +105 -0
  140. canvas-0.77.0/canvas_sdk/commands/commands/medical_history.py +21 -0
  141. canvas-0.77.0/canvas_sdk/commands/commands/medication_statement.py +43 -0
  142. canvas-0.77.0/canvas_sdk/commands/commands/past_surgical_history.py +34 -0
  143. canvas-0.77.0/canvas_sdk/commands/commands/perform.py +33 -0
  144. canvas-0.77.0/canvas_sdk/commands/commands/plan.py +13 -0
  145. canvas-0.77.0/canvas_sdk/commands/commands/prescribe.py +222 -0
  146. canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/__init__.py +107 -0
  147. canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/question.py +145 -0
  148. canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/toggle_questions.py +68 -0
  149. canvas-0.77.0/canvas_sdk/commands/commands/reason_for_visit.py +52 -0
  150. canvas-0.77.0/canvas_sdk/commands/commands/refer.py +53 -0
  151. canvas-0.77.0/canvas_sdk/commands/commands/refill.py +39 -0
  152. canvas-0.77.0/canvas_sdk/commands/commands/remove_allergy.py +20 -0
  153. canvas-0.77.0/canvas_sdk/commands/commands/resolve_condition.py +47 -0
  154. canvas-0.77.0/canvas_sdk/commands/commands/review_of_systems.py +12 -0
  155. canvas-0.77.0/canvas_sdk/commands/commands/stop_medication.py +19 -0
  156. canvas-0.77.0/canvas_sdk/commands/commands/structured_assessment.py +11 -0
  157. canvas-0.77.0/canvas_sdk/commands/commands/task.py +44 -0
  158. canvas-0.77.0/canvas_sdk/commands/commands/update_diagnosis.py +22 -0
  159. canvas-0.77.0/canvas_sdk/commands/commands/update_goal.py +40 -0
  160. canvas-0.77.0/canvas_sdk/commands/commands/vitals.py +56 -0
  161. canvas-0.77.0/canvas_sdk/commands/constants.py +60 -0
  162. canvas-0.77.0/canvas_sdk/effects/__init__.py +5 -0
  163. canvas-0.77.0/canvas_sdk/effects/appointments_metadata/__init__.py +13 -0
  164. canvas-0.77.0/canvas_sdk/effects/appointments_metadata/appointments_metadata_create_form.py +12 -0
  165. canvas-0.77.0/canvas_sdk/effects/appointments_metadata/base.py +30 -0
  166. canvas-0.77.0/canvas_sdk/effects/banner_alert/__init__.py +4 -0
  167. canvas-0.77.0/canvas_sdk/effects/banner_alert/add_banner_alert.py +64 -0
  168. canvas-0.77.0/canvas_sdk/effects/banner_alert/remove_banner_alert.py +24 -0
  169. canvas-0.77.0/canvas_sdk/effects/base.py +35 -0
  170. canvas-0.77.0/canvas_sdk/effects/batch_originate.py +22 -0
  171. canvas-0.77.0/canvas_sdk/effects/billing_line_item/__init__.py +15 -0
  172. canvas-0.77.0/canvas_sdk/effects/billing_line_item/add_billing_line_item.py +41 -0
  173. canvas-0.77.0/canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +25 -0
  174. canvas-0.77.0/canvas_sdk/effects/billing_line_item/update_billing_line_item.py +47 -0
  175. canvas-0.77.0/canvas_sdk/effects/calendar/__init__.py +4 -0
  176. canvas-0.77.0/canvas_sdk/effects/calendar/create_calendar.py +40 -0
  177. canvas-0.77.0/canvas_sdk/effects/calendar/create_event.py +43 -0
  178. canvas-0.77.0/canvas_sdk/effects/claim_label.py +93 -0
  179. canvas-0.77.0/canvas_sdk/effects/claim_line_item.py +47 -0
  180. canvas-0.77.0/canvas_sdk/effects/claim_queue.py +49 -0
  181. canvas-0.77.0/canvas_sdk/effects/compound_medications/__init__.py +3 -0
  182. canvas-0.77.0/canvas_sdk/effects/compound_medications/compound_medication.py +275 -0
  183. canvas-0.77.0/canvas_sdk/effects/fax/__init__.py +3 -0
  184. canvas-0.77.0/canvas_sdk/effects/fax/base.py +77 -0
  185. canvas-0.77.0/canvas_sdk/effects/fax/note.py +42 -0
  186. canvas-0.77.0/canvas_sdk/effects/form.py +69 -0
  187. canvas-0.77.0/canvas_sdk/effects/generate_full_chart_pdf.py +56 -0
  188. canvas-0.77.0/canvas_sdk/effects/group.py +20 -0
  189. canvas-0.77.0/canvas_sdk/effects/launch_modal.py +46 -0
  190. canvas-0.77.0/canvas_sdk/effects/metadata.py +40 -0
  191. canvas-0.77.0/canvas_sdk/effects/note/__init__.py +17 -0
  192. canvas-0.77.0/canvas_sdk/effects/note/appointment.py +359 -0
  193. canvas-0.77.0/canvas_sdk/effects/note/base.py +260 -0
  194. canvas-0.77.0/canvas_sdk/effects/note/message.py +131 -0
  195. canvas-0.77.0/canvas_sdk/effects/note/note.py +186 -0
  196. canvas-0.77.0/canvas_sdk/effects/panel_configuration.py +90 -0
  197. canvas-0.77.0/canvas_sdk/effects/patient/__init__.py +25 -0
  198. canvas-0.77.0/canvas_sdk/effects/patient/base.py +283 -0
  199. canvas-0.77.0/canvas_sdk/effects/patient/create_patient_external_identifier.py +40 -0
  200. canvas-0.77.0/canvas_sdk/effects/patient/create_patient_preferred_pharmacies.py +70 -0
  201. canvas-0.77.0/canvas_sdk/effects/patient_chart_group.py +30 -0
  202. canvas-0.77.0/canvas_sdk/effects/patient_chart_summary_configuration.py +43 -0
  203. canvas-0.77.0/canvas_sdk/effects/patient_metadata/__init__.py +13 -0
  204. canvas-0.77.0/canvas_sdk/effects/patient_metadata/base.py +32 -0
  205. canvas-0.77.0/canvas_sdk/effects/patient_metadata/patient_metadata_create_form.py +12 -0
  206. canvas-0.77.0/canvas_sdk/effects/patient_portal/__init__.py +1 -0
  207. canvas-0.77.0/canvas_sdk/effects/patient_portal/application_configuration.py +25 -0
  208. canvas-0.77.0/canvas_sdk/effects/patient_portal/form_result.py +34 -0
  209. canvas-0.77.0/canvas_sdk/effects/patient_portal_menu_configuration.py +39 -0
  210. canvas-0.77.0/canvas_sdk/effects/patient_profile_configuration.py +48 -0
  211. canvas-0.77.0/canvas_sdk/effects/payment_processor.py +137 -0
  212. canvas-0.77.0/canvas_sdk/effects/protocol_card/__init__.py +6 -0
  213. canvas-0.77.0/canvas_sdk/effects/protocol_card/protocol_card.py +103 -0
  214. canvas-0.77.0/canvas_sdk/effects/questionnaire_result.py +32 -0
  215. canvas-0.77.0/canvas_sdk/effects/send_contact_verification.py +42 -0
  216. canvas-0.77.0/canvas_sdk/effects/send_invite.py +46 -0
  217. canvas-0.77.0/canvas_sdk/effects/show_button.py +32 -0
  218. canvas-0.77.0/canvas_sdk/effects/simple_api.py +151 -0
  219. canvas-0.77.0/canvas_sdk/effects/surescripts/__init__.py +11 -0
  220. canvas-0.77.0/canvas_sdk/effects/surescripts/surescripts_messages.py +100 -0
  221. canvas-0.77.0/canvas_sdk/effects/task/__init__.py +9 -0
  222. canvas-0.77.0/canvas_sdk/effects/task/task.py +178 -0
  223. canvas-0.77.0/canvas_sdk/effects/update_user.py +81 -0
  224. canvas-0.77.0/canvas_sdk/effects/widgets/__init__.py +3 -0
  225. canvas-0.77.0/canvas_sdk/effects/widgets/portal_widget.py +79 -0
  226. canvas-0.77.0/canvas_sdk/events/__init__.py +11 -0
  227. canvas-0.77.0/canvas_sdk/events/base.py +66 -0
  228. canvas-0.77.0/canvas_sdk/handlers/__init__.py +3 -0
  229. canvas-0.77.0/canvas_sdk/handlers/action_button.py +86 -0
  230. canvas-0.77.0/canvas_sdk/handlers/application.py +44 -0
  231. canvas-0.77.0/canvas_sdk/handlers/base.py +62 -0
  232. canvas-0.77.0/canvas_sdk/handlers/cron_task.py +38 -0
  233. canvas-0.77.0/canvas_sdk/handlers/payment_processors/__init__.py +1 -0
  234. canvas-0.77.0/canvas_sdk/handlers/payment_processors/base.py +93 -0
  235. canvas-0.77.0/canvas_sdk/handlers/payment_processors/card.py +200 -0
  236. canvas-0.77.0/canvas_sdk/handlers/simple_api/__init__.py +29 -0
  237. canvas-0.77.0/canvas_sdk/handlers/simple_api/api.py +539 -0
  238. canvas-0.77.0/canvas_sdk/handlers/simple_api/exceptions.py +49 -0
  239. canvas-0.77.0/canvas_sdk/handlers/simple_api/security.py +265 -0
  240. canvas-0.77.0/canvas_sdk/handlers/simple_api/tools.py +124 -0
  241. canvas-0.77.0/canvas_sdk/handlers/simple_api/websocket.py +79 -0
  242. canvas-0.77.0/canvas_sdk/handlers/utils.py +14 -0
  243. canvas-0.77.0/canvas_sdk/protocols/__init__.py +4 -0
  244. canvas-0.77.0/canvas_sdk/protocols/base.py +14 -0
  245. canvas-0.77.0/canvas_sdk/protocols/clinical_quality_measure.py +137 -0
  246. canvas-0.77.0/canvas_sdk/protocols/timeframe.py +42 -0
  247. canvas-0.77.0/canvas_sdk/questionnaires/__init__.py +3 -0
  248. canvas-0.77.0/canvas_sdk/questionnaires/utils.py +125 -0
  249. canvas-0.77.0/canvas_sdk/templates/__init__.py +3 -0
  250. canvas-0.77.0/canvas_sdk/templates/utils.py +57 -0
  251. canvas-0.77.0/canvas_sdk/test_utils/__init__.py +0 -0
  252. canvas-0.77.0/canvas_sdk/test_utils/factories/__init__.py +69 -0
  253. canvas-0.77.0/canvas_sdk/test_utils/factories/claim.py +53 -0
  254. canvas-0.77.0/canvas_sdk/test_utils/factories/claim_diagnosis_code.py +16 -0
  255. canvas-0.77.0/canvas_sdk/test_utils/factories/facility.py +21 -0
  256. canvas-0.77.0/canvas_sdk/test_utils/factories/medication_history.py +75 -0
  257. canvas-0.77.0/canvas_sdk/test_utils/factories/note.py +37 -0
  258. canvas-0.77.0/canvas_sdk/test_utils/factories/organization.py +20 -0
  259. canvas-0.77.0/canvas_sdk/test_utils/factories/patient.py +51 -0
  260. canvas-0.77.0/canvas_sdk/test_utils/factories/practicelocation.py +34 -0
  261. canvas-0.77.0/canvas_sdk/test_utils/factories/protocol_current.py +44 -0
  262. canvas-0.77.0/canvas_sdk/test_utils/factories/staff.py +111 -0
  263. canvas-0.77.0/canvas_sdk/test_utils/factories/task.py +66 -0
  264. canvas-0.77.0/canvas_sdk/test_utils/factories/user.py +13 -0
  265. canvas-0.77.0/canvas_sdk/utils/__init__.py +9 -0
  266. canvas-0.77.0/canvas_sdk/utils/db.py +14 -0
  267. canvas-0.77.0/canvas_sdk/utils/http.py +364 -0
  268. canvas-0.77.0/canvas_sdk/utils/metrics.py +195 -0
  269. canvas-0.77.0/canvas_sdk/utils/plugins.py +66 -0
  270. canvas-0.77.0/canvas_sdk/v1/__init__.py +1 -0
  271. canvas-0.77.0/canvas_sdk/v1/apps.py +10 -0
  272. canvas-0.77.0/canvas_sdk/v1/data/__init__.py +254 -0
  273. canvas-0.77.0/canvas_sdk/v1/data/allergy_intolerance.py +77 -0
  274. canvas-0.77.0/canvas_sdk/v1/data/appointment.py +114 -0
  275. canvas-0.77.0/canvas_sdk/v1/data/assessment.py +36 -0
  276. canvas-0.77.0/canvas_sdk/v1/data/banner_alert.py +28 -0
  277. canvas-0.77.0/canvas_sdk/v1/data/base.py +264 -0
  278. canvas-0.77.0/canvas_sdk/v1/data/billing.py +84 -0
  279. canvas-0.77.0/canvas_sdk/v1/data/business_line.py +34 -0
  280. canvas-0.77.0/canvas_sdk/v1/data/care_team.py +58 -0
  281. canvas-0.77.0/canvas_sdk/v1/data/charge_description_master.py +29 -0
  282. canvas-0.77.0/canvas_sdk/v1/data/claim.py +381 -0
  283. canvas-0.77.0/canvas_sdk/v1/data/claim_diagnosis_code.py +19 -0
  284. canvas-0.77.0/canvas_sdk/v1/data/claim_line_item.py +136 -0
  285. canvas-0.77.0/canvas_sdk/v1/data/coding.py +19 -0
  286. canvas-0.77.0/canvas_sdk/v1/data/command.py +50 -0
  287. canvas-0.77.0/canvas_sdk/v1/data/common.py +174 -0
  288. canvas-0.77.0/canvas_sdk/v1/data/compound_medication.py +66 -0
  289. canvas-0.77.0/canvas_sdk/v1/data/condition.py +82 -0
  290. canvas-0.77.0/canvas_sdk/v1/data/coverage.py +310 -0
  291. canvas-0.77.0/canvas_sdk/v1/data/detected_issue.py +56 -0
  292. canvas-0.77.0/canvas_sdk/v1/data/device.py +38 -0
  293. canvas-0.77.0/canvas_sdk/v1/data/discount.py +18 -0
  294. canvas-0.77.0/canvas_sdk/v1/data/encounter.py +44 -0
  295. canvas-0.77.0/canvas_sdk/v1/data/facility.py +28 -0
  296. canvas-0.77.0/canvas_sdk/v1/data/fields.py +37 -0
  297. canvas-0.77.0/canvas_sdk/v1/data/goal.py +58 -0
  298. canvas-0.77.0/canvas_sdk/v1/data/imaging.py +115 -0
  299. canvas-0.77.0/canvas_sdk/v1/data/immunization.py +149 -0
  300. canvas-0.77.0/canvas_sdk/v1/data/invoice.py +62 -0
  301. canvas-0.77.0/canvas_sdk/v1/data/lab.py +323 -0
  302. canvas-0.77.0/canvas_sdk/v1/data/line_item_transaction.py +78 -0
  303. canvas-0.77.0/canvas_sdk/v1/data/medication.py +73 -0
  304. canvas-0.77.0/canvas_sdk/v1/data/medication_history.py +142 -0
  305. canvas-0.77.0/canvas_sdk/v1/data/medication_statement.py +41 -0
  306. canvas-0.77.0/canvas_sdk/v1/data/message.py +71 -0
  307. canvas-0.77.0/canvas_sdk/v1/data/note.py +235 -0
  308. canvas-0.77.0/canvas_sdk/v1/data/observation.py +103 -0
  309. canvas-0.77.0/canvas_sdk/v1/data/organization.py +30 -0
  310. canvas-0.77.0/canvas_sdk/v1/data/patient.py +317 -0
  311. canvas-0.77.0/canvas_sdk/v1/data/patient_consent.py +77 -0
  312. canvas-0.77.0/canvas_sdk/v1/data/payment_collection.py +31 -0
  313. canvas-0.77.0/canvas_sdk/v1/data/payor_specific_charge.py +26 -0
  314. canvas-0.77.0/canvas_sdk/v1/data/posting.py +211 -0
  315. canvas-0.77.0/canvas_sdk/v1/data/practicelocation.py +104 -0
  316. canvas-0.77.0/canvas_sdk/v1/data/protocol_current.py +23 -0
  317. canvas-0.77.0/canvas_sdk/v1/data/protocol_override.py +77 -0
  318. canvas-0.77.0/canvas_sdk/v1/data/protocol_result.py +46 -0
  319. canvas-0.77.0/canvas_sdk/v1/data/questionnaire.py +196 -0
  320. canvas-0.77.0/canvas_sdk/v1/data/reason_for_visit.py +19 -0
  321. canvas-0.77.0/canvas_sdk/v1/data/referral.py +88 -0
  322. canvas-0.77.0/canvas_sdk/v1/data/service_provider.py +54 -0
  323. canvas-0.77.0/canvas_sdk/v1/data/staff.py +257 -0
  324. canvas-0.77.0/canvas_sdk/v1/data/stop_medication_event.py +27 -0
  325. canvas-0.77.0/canvas_sdk/v1/data/task.py +131 -0
  326. canvas-0.77.0/canvas_sdk/v1/data/team.py +78 -0
  327. canvas-0.77.0/canvas_sdk/v1/data/user.py +32 -0
  328. canvas-0.77.0/canvas_sdk/v1/data/utils.py +37 -0
  329. canvas-0.77.0/canvas_sdk/v1/models.py +6 -0
  330. canvas-0.77.0/canvas_sdk/value_set/__init__.py +1 -0
  331. canvas-0.77.0/canvas_sdk/value_set/custom.py +1073 -0
  332. canvas-0.77.0/canvas_sdk/value_set/hcc2018.py +55372 -0
  333. canvas-0.77.0/canvas_sdk/value_set/v2022/__init__.py +1 -0
  334. canvas-0.77.0/canvas_sdk/value_set/v2022/adverse_event.py +36 -0
  335. canvas-0.77.0/canvas_sdk/value_set/v2022/allergy.py +242 -0
  336. canvas-0.77.0/canvas_sdk/value_set/v2022/assessment.py +227 -0
  337. canvas-0.77.0/canvas_sdk/value_set/v2022/communication.py +332 -0
  338. canvas-0.77.0/canvas_sdk/value_set/v2022/condition.py +40831 -0
  339. canvas-0.77.0/canvas_sdk/value_set/v2022/device.py +180 -0
  340. canvas-0.77.0/canvas_sdk/value_set/v2022/diagnostic_study.py +4982 -0
  341. canvas-0.77.0/canvas_sdk/value_set/v2022/encounter.py +2624 -0
  342. canvas-0.77.0/canvas_sdk/value_set/v2022/immunization.py +358 -0
  343. canvas-0.77.0/canvas_sdk/value_set/v2022/individual_characteristic.py +323 -0
  344. canvas-0.77.0/canvas_sdk/value_set/v2022/intervention.py +1362 -0
  345. canvas-0.77.0/canvas_sdk/value_set/v2022/laboratory_test.py +1279 -0
  346. canvas-0.77.0/canvas_sdk/value_set/v2022/medication.py +5225 -0
  347. canvas-0.77.0/canvas_sdk/value_set/v2022/physical_exam.py +212 -0
  348. canvas-0.77.0/canvas_sdk/value_set/v2022/procedure.py +4084 -0
  349. canvas-0.77.0/canvas_sdk/value_set/v2022/symptom.py +179 -0
  350. canvas-0.77.0/canvas_sdk/value_set/value_set.py +121 -0
  351. canvas-0.77.0/canvas_sdk/views/__init__.py +1 -0
  352. canvas-0.77.0/logger/__init__.py +5 -0
  353. canvas-0.77.0/logger/logger.py +75 -0
  354. canvas-0.77.0/plugin_runner/__init__.py +0 -0
  355. canvas-0.77.0/plugin_runner/allowed-module-imports.json +1537 -0
  356. canvas-0.77.0/plugin_runner/authentication.py +45 -0
  357. canvas-0.77.0/plugin_runner/aws_headers.py +77 -0
  358. canvas-0.77.0/plugin_runner/exceptions.py +18 -0
  359. canvas-0.77.0/plugin_runner/generate_allowed_imports.py +97 -0
  360. canvas-0.77.0/plugin_runner/installation.py +274 -0
  361. canvas-0.77.0/plugin_runner/load_all_plugins.py +199 -0
  362. canvas-0.77.0/plugin_runner/plugin_runner.py +779 -0
  363. canvas-0.77.0/plugin_runner/sandbox.py +958 -0
  364. canvas-0.77.0/protobufs/canvas_generated/messages/effects.proto +377 -0
  365. canvas-0.77.0/protobufs/canvas_generated/messages/events.proto +1235 -0
  366. canvas-0.77.0/protobufs/canvas_generated/messages/plugins.proto +24 -0
  367. canvas-0.77.0/protobufs/canvas_generated/services/plugin_runner.proto +16 -0
  368. canvas-0.77.0/pubsub/__init__.py +0 -0
  369. canvas-0.77.0/pubsub/pubsub.py +47 -0
  370. canvas-0.77.0/pyproject.toml +205 -0
  371. canvas-0.77.0/settings.py +196 -0
@@ -0,0 +1,20 @@
1
+ # MacOS artifacts
2
+ .DS_Store
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+
7
+ dist/
8
+
9
+ # vim
10
+ *.swp
11
+
12
+ .env
13
+
14
+ # JetBrains
15
+ .idea/
16
+
17
+ # SQLite databases
18
+ *.sqlite3
19
+
20
+ profile-imports-*.txt
canvas-0.77.0/PKG-INFO ADDED
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: canvas
3
+ Version: 0.77.0
4
+ Summary: SDK to customize event-driven actions in your Canvas instance
5
+ Author-email: Canvas Team <engineering@canvasmedical.com>
6
+ License-Expression: MIT
7
+ Requires-Python: <3.13,>=3.11
8
+ Requires-Dist: cookiecutter
9
+ Requires-Dist: cron-converter<2,>=1.2.1
10
+ Requires-Dist: cryptography>=45.0.5
11
+ Requires-Dist: deprecation<3,>=2.1.0
12
+ Requires-Dist: django-stubs[compatible-mypy]<6,>=5.1.1
13
+ Requires-Dist: django-timezone-utils<0.16,>=0.15.0
14
+ Requires-Dist: django<6,>=5.1.1
15
+ Requires-Dist: env-tools<3,>=2.4.0
16
+ Requires-Dist: factory-boy>=3.3.3
17
+ Requires-Dist: frozendict>=2.4.6
18
+ Requires-Dist: grpcio<2,>=1.60.1
19
+ Requires-Dist: ipython<9,>=8.21.0
20
+ Requires-Dist: jsonschema<5,>=4.21.1
21
+ Requires-Dist: pathspec>=0.12.1
22
+ Requires-Dist: protobuf<5,>=4.25.3
23
+ Requires-Dist: psycopg[binary,pool]<4,>=3.2.2
24
+ Requires-Dist: pydantic<3,>=2.6.1
25
+ Requires-Dist: pyjwt==2.10.1
26
+ Requires-Dist: python-dotenv<2,>=1.0.1
27
+ Requires-Dist: rapidfuzz<4,>=3.10.1
28
+ Requires-Dist: redis<6,>=5.0.4
29
+ Requires-Dist: requests
30
+ Requires-Dist: restrictedpython>=8.0
31
+ Requires-Dist: sentry-sdk>=2.33.2
32
+ Requires-Dist: statsd<5,>=4.0.1
33
+ Requires-Dist: typer
34
+ Requires-Dist: typing-extensions<4.13,>=4.8
35
+ Requires-Dist: websocket-client<2,>=1.7.0
36
+ Provides-Extra: test-utils
37
+ Requires-Dist: pytest-canvas; extra == 'test-utils'
38
+ Description-Content-Type: text/markdown
39
+
40
+ [![codecov](https://codecov.io/gh/canvas-medical/canvas-plugins/graph/badge.svg?token=P8JJUOJ8FH)](https://codecov.io/gh/canvas-medical/canvas-plugins)
41
+
42
+ ### Getting Started
43
+
44
+ Create a file `~/.canvas/credentials.ini` and add the client_id and client_secret credentials for each of your Canvas instances. You can define your default host with `is_default=true`. If no default is explicitly defined, the Canvas CLI will use the first instance in the file as the default for each of the CLI commands.
45
+
46
+ **Example:**
47
+
48
+ ```
49
+ [my-canvas-instance]
50
+ client_id=myclientid
51
+ client_secret=myclientsecret
52
+
53
+ [my-dev-canvas-instance]
54
+ client_id=devclientid
55
+ client_secret=devclientsecret
56
+ is_default=true
57
+
58
+ [localhost]
59
+ client_id=localclientid
60
+ client_secret=localclientsecret
61
+ ```
62
+
63
+ Next, you're ready to install canvas.
64
+
65
+ `pip install canvas`
66
+
67
+ **Usage**:
68
+
69
+ ```console
70
+ $ canvas [OPTIONS] COMMAND [ARGS]...
71
+ ```
72
+
73
+ **Options**:
74
+
75
+ - `--version`
76
+ - `--help`: Show this message and exit.
77
+
78
+ **Commands**:
79
+
80
+ - `init`: Create a new plugin
81
+ - `install`: Install a plugin into a Canvas instance
82
+ - `uninstall`: Uninstall a plugin from a Canvas instance
83
+ - `disable`: Disable a plugin from a Canvas instance
84
+ - `enable`: Enable a plugin from a Canvas instance
85
+ - `list`: List all plugins from a Canvas instance
86
+ - `validate-manifest`: Validate the Canvas Manifest json file
87
+ - `logs`: Listen and print log streams from a Canvas instance
88
+
89
+ ## `canvas init`
90
+
91
+ Create a new plugin.
92
+
93
+ **Usage**:
94
+
95
+ ```console
96
+ $ canvas init [OPTIONS]
97
+ ```
98
+
99
+ **Options**:
100
+
101
+ - `--help`: Show this message and exit.
102
+
103
+ ## `canvas install`
104
+
105
+ Install a plugin into a Canvas instance.
106
+
107
+ **Usage**:
108
+
109
+ ```console
110
+ $ canvas install [OPTIONS] PLUGIN_NAME
111
+ ```
112
+
113
+ **Arguments**:
114
+
115
+ - `PLUGIN_NAME`: Path to plugin to install [required]
116
+
117
+ **Options**:
118
+
119
+ - `--host TEXT`: Canvas instance to connect to
120
+ - `--help`: Show this message and exit.
121
+
122
+ ## `canvas uninstall`
123
+
124
+ Uninstall a plugin from a Canvas instance..
125
+
126
+ **Usage**:
127
+
128
+ ```console
129
+ $ canvas uninstall [OPTIONS] NAME
130
+ ```
131
+
132
+ **Arguments**:
133
+
134
+ - `NAME`: Plugin name to delete [required]
135
+
136
+ **Options**:
137
+
138
+ - `--host TEXT`: Canvas instance to connect to
139
+ - `--help`: Show this message and exit.
140
+
141
+ ## `canvas enable`
142
+
143
+ Enable a plugin from a Canvas instance..
144
+
145
+ **Usage**:
146
+
147
+ ```console
148
+ $ canvas enable [OPTIONS] NAME
149
+ ```
150
+
151
+ **Arguments**:
152
+
153
+ - `NAME`: Plugin name to enable [required]
154
+
155
+ **Options**:
156
+
157
+ - `--host TEXT`: Canvas instance to connect to
158
+ - `--help`: Show this message and exit.
159
+
160
+ ## `canvas disable`
161
+
162
+ Disable a plugin from a Canvas instance..
163
+
164
+ **Usage**:
165
+
166
+ ```console
167
+ $ canvas disable [OPTIONS] NAME
168
+ ```
169
+
170
+ **Arguments**:
171
+
172
+ - `NAME`: Plugin name to disable [required]
173
+
174
+ **Options**:
175
+
176
+ - `--host TEXT`: Canvas instance to connect to
177
+ - `--help`: Show this message and exit.
178
+
179
+ ## `canvas list`
180
+
181
+ List all plugins from a Canvas instance.
182
+
183
+ **Usage**:
184
+
185
+ ```console
186
+ $ canvas list [OPTIONS]
187
+ ```
188
+
189
+ **Options**:
190
+
191
+ - `--host TEXT`: Canvas instance to connect to
192
+ - `--help`: Show this message and exit.
193
+
194
+ ## `canvas validate-manifest`
195
+
196
+ Validate the Canvas Manifest json file.
197
+
198
+ **Usage**:
199
+
200
+ ```console
201
+ $ canvas validate-manifest [OPTIONS] PACKAGE
202
+ ```
203
+
204
+ **Arguments**:
205
+
206
+ - `PLUGIN_NAME`: Path to plugin to install [required]
207
+
208
+ **Options**:
209
+
210
+ - `--help`: Show this message and exit.
211
+
212
+ ## `canvas logs`
213
+
214
+ Listens and prints log streams from the instance.
215
+
216
+ **Usage**:
217
+
218
+ ```console
219
+ $ canvas logs [OPTIONS]
220
+ ```
221
+
222
+ **Options**:
223
+
224
+ - `--host TEXT`: Canvas instance to connect to
225
+ - `--help`: Show this message and exit.
@@ -0,0 +1,186 @@
1
+ [![codecov](https://codecov.io/gh/canvas-medical/canvas-plugins/graph/badge.svg?token=P8JJUOJ8FH)](https://codecov.io/gh/canvas-medical/canvas-plugins)
2
+
3
+ ### Getting Started
4
+
5
+ Create a file `~/.canvas/credentials.ini` and add the client_id and client_secret credentials for each of your Canvas instances. You can define your default host with `is_default=true`. If no default is explicitly defined, the Canvas CLI will use the first instance in the file as the default for each of the CLI commands.
6
+
7
+ **Example:**
8
+
9
+ ```
10
+ [my-canvas-instance]
11
+ client_id=myclientid
12
+ client_secret=myclientsecret
13
+
14
+ [my-dev-canvas-instance]
15
+ client_id=devclientid
16
+ client_secret=devclientsecret
17
+ is_default=true
18
+
19
+ [localhost]
20
+ client_id=localclientid
21
+ client_secret=localclientsecret
22
+ ```
23
+
24
+ Next, you're ready to install canvas.
25
+
26
+ `pip install canvas`
27
+
28
+ **Usage**:
29
+
30
+ ```console
31
+ $ canvas [OPTIONS] COMMAND [ARGS]...
32
+ ```
33
+
34
+ **Options**:
35
+
36
+ - `--version`
37
+ - `--help`: Show this message and exit.
38
+
39
+ **Commands**:
40
+
41
+ - `init`: Create a new plugin
42
+ - `install`: Install a plugin into a Canvas instance
43
+ - `uninstall`: Uninstall a plugin from a Canvas instance
44
+ - `disable`: Disable a plugin from a Canvas instance
45
+ - `enable`: Enable a plugin from a Canvas instance
46
+ - `list`: List all plugins from a Canvas instance
47
+ - `validate-manifest`: Validate the Canvas Manifest json file
48
+ - `logs`: Listen and print log streams from a Canvas instance
49
+
50
+ ## `canvas init`
51
+
52
+ Create a new plugin.
53
+
54
+ **Usage**:
55
+
56
+ ```console
57
+ $ canvas init [OPTIONS]
58
+ ```
59
+
60
+ **Options**:
61
+
62
+ - `--help`: Show this message and exit.
63
+
64
+ ## `canvas install`
65
+
66
+ Install a plugin into a Canvas instance.
67
+
68
+ **Usage**:
69
+
70
+ ```console
71
+ $ canvas install [OPTIONS] PLUGIN_NAME
72
+ ```
73
+
74
+ **Arguments**:
75
+
76
+ - `PLUGIN_NAME`: Path to plugin to install [required]
77
+
78
+ **Options**:
79
+
80
+ - `--host TEXT`: Canvas instance to connect to
81
+ - `--help`: Show this message and exit.
82
+
83
+ ## `canvas uninstall`
84
+
85
+ Uninstall a plugin from a Canvas instance..
86
+
87
+ **Usage**:
88
+
89
+ ```console
90
+ $ canvas uninstall [OPTIONS] NAME
91
+ ```
92
+
93
+ **Arguments**:
94
+
95
+ - `NAME`: Plugin name to delete [required]
96
+
97
+ **Options**:
98
+
99
+ - `--host TEXT`: Canvas instance to connect to
100
+ - `--help`: Show this message and exit.
101
+
102
+ ## `canvas enable`
103
+
104
+ Enable a plugin from a Canvas instance..
105
+
106
+ **Usage**:
107
+
108
+ ```console
109
+ $ canvas enable [OPTIONS] NAME
110
+ ```
111
+
112
+ **Arguments**:
113
+
114
+ - `NAME`: Plugin name to enable [required]
115
+
116
+ **Options**:
117
+
118
+ - `--host TEXT`: Canvas instance to connect to
119
+ - `--help`: Show this message and exit.
120
+
121
+ ## `canvas disable`
122
+
123
+ Disable a plugin from a Canvas instance..
124
+
125
+ **Usage**:
126
+
127
+ ```console
128
+ $ canvas disable [OPTIONS] NAME
129
+ ```
130
+
131
+ **Arguments**:
132
+
133
+ - `NAME`: Plugin name to disable [required]
134
+
135
+ **Options**:
136
+
137
+ - `--host TEXT`: Canvas instance to connect to
138
+ - `--help`: Show this message and exit.
139
+
140
+ ## `canvas list`
141
+
142
+ List all plugins from a Canvas instance.
143
+
144
+ **Usage**:
145
+
146
+ ```console
147
+ $ canvas list [OPTIONS]
148
+ ```
149
+
150
+ **Options**:
151
+
152
+ - `--host TEXT`: Canvas instance to connect to
153
+ - `--help`: Show this message and exit.
154
+
155
+ ## `canvas validate-manifest`
156
+
157
+ Validate the Canvas Manifest json file.
158
+
159
+ **Usage**:
160
+
161
+ ```console
162
+ $ canvas validate-manifest [OPTIONS] PACKAGE
163
+ ```
164
+
165
+ **Arguments**:
166
+
167
+ - `PLUGIN_NAME`: Path to plugin to install [required]
168
+
169
+ **Options**:
170
+
171
+ - `--help`: Show this message and exit.
172
+
173
+ ## `canvas logs`
174
+
175
+ Listens and prints log streams from the instance.
176
+
177
+ **Usage**:
178
+
179
+ ```console
180
+ $ canvas logs [OPTIONS]
181
+ ```
182
+
183
+ **Options**:
184
+
185
+ - `--host TEXT`: Canvas instance to connect to
186
+ - `--help`: Show this message and exit.
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ from canvas_cli.apps.auth.utils import get_or_request_api_token
2
+
3
+ __all__ = ("get_or_request_api_token",)
@@ -0,0 +1,65 @@
1
+ import json
2
+ from datetime import datetime
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ TOKENS_PATH = Path.home() / ".canvas" / "tokens.json"
7
+ TOKENS_PATH.parent.mkdir(parents=True, exist_ok=True)
8
+
9
+
10
+ def _load_tokens() -> dict:
11
+ if not TOKENS_PATH.exists():
12
+ return {}
13
+ with TOKENS_PATH.open("r") as f:
14
+ return json.load(f)
15
+
16
+
17
+ def _save_tokens(tokens: dict) -> None:
18
+ with TOKENS_PATH.open("w") as f:
19
+ json.dump(tokens, f, indent=2)
20
+
21
+
22
+ def _set_value(key: str, value: Any) -> None:
23
+ """Set a value in the token storage."""
24
+ tokens = _load_tokens()
25
+ tokens[key] = value
26
+ _save_tokens(tokens)
27
+
28
+
29
+ def _get_value(key: str) -> Any | None:
30
+ """Get value from the token storage."""
31
+ tokens = _load_tokens()
32
+ return tokens.get(key)
33
+
34
+
35
+ def _delete_value(key: str) -> None:
36
+ """Delete a value from the token storage."""
37
+ tokens = _load_tokens()
38
+ tokens.pop(key, None)
39
+ _save_tokens(tokens)
40
+
41
+
42
+ def set_token(host_token_key: str, token: str, exp: datetime) -> None:
43
+ """Set a token with an expiry date in the token storage."""
44
+ _set_value(host_token_key, {"token": token, "exp_date": exp.isoformat()})
45
+
46
+
47
+ def get_token(host_token_key: str) -> str | None:
48
+ """Get a token from the token storage."""
49
+ value = _get_value(host_token_key)
50
+
51
+ if not value:
52
+ return None
53
+ try:
54
+ exp = value["exp_date"]
55
+ if datetime.fromisoformat(exp) <= datetime.now():
56
+ return None
57
+ except ValueError:
58
+ return None
59
+
60
+ return value["token"]
61
+
62
+
63
+ def delete_token(host_token_key: str) -> None:
64
+ """Delete a token from the token storage."""
65
+ _delete_value(host_token_key)
@@ -0,0 +1,127 @@
1
+ import configparser
2
+ from datetime import datetime, timedelta
3
+ from pathlib import Path
4
+ from urllib.parse import urlparse
5
+
6
+ import requests
7
+
8
+ from canvas_cli.apps.auth.storage import get_token, set_token
9
+ from canvas_sdk.utils import Http
10
+
11
+ CONFIG_PATH = Path.home() / ".canvas" / "credentials.ini"
12
+
13
+ LOCALHOST = "http://localhost:8000"
14
+
15
+
16
+ def get_config() -> configparser.ConfigParser:
17
+ """Reads the config file and returns a ConfigParser object."""
18
+ config = configparser.ConfigParser()
19
+ if not config.read(CONFIG_PATH):
20
+ raise Exception(
21
+ f"""Please add your configuration file at '{CONFIG_PATH}' with the following format:
22
+
23
+ [my-canvas-subdomain]
24
+ client_id=myclientid
25
+ client_secret=myclientsecret
26
+
27
+ [my-dev-canvas-subdomain]
28
+ client_id=devclientid
29
+ client_secret=devclientsecret
30
+ is_default=true
31
+
32
+ [localhost]
33
+ client_id=localclientid
34
+ client_secret=localclientsecret
35
+ """
36
+ )
37
+ return config
38
+
39
+
40
+ def read_config(host: str, property: str) -> str:
41
+ """Reads the config file and returns the property for a given section."""
42
+ config = get_config()
43
+ if host not in config:
44
+ raise Exception(f"'{host}' is not found in the configuration file at '{CONFIG_PATH}'")
45
+ return config.get(host, property)
46
+
47
+
48
+ def get_api_client_credentials(host: str) -> str:
49
+ """Either return the given api_key, or fetch it from the token storage."""
50
+ hostname = urlparse(host).hostname
51
+
52
+ if not hostname:
53
+ raise ValueError("Could not parse hostname from URL")
54
+
55
+ instance = hostname.removesuffix(".canvasmedical.com")
56
+
57
+ client_id = read_config(instance, "client_id")
58
+ client_secret = read_config(instance, "client_secret")
59
+
60
+ return f"client_id={client_id}&client_secret={client_secret}"
61
+
62
+
63
+ def get_default_host(host: str | None = None) -> str:
64
+ """Return the explicitly stated default host, or first if none is indicated."""
65
+ if host:
66
+ if "://" in host:
67
+ return host
68
+
69
+ if "localhost" in host:
70
+ return LOCALHOST
71
+
72
+ return f"https://{host}.canvasmedical.com"
73
+
74
+ config = get_config()
75
+ if not (hosts := config.sections()):
76
+ raise Exception(f"No hosts found in the configuration file at '{CONFIG_PATH}'")
77
+
78
+ first_default_host = next(
79
+ (host for host in hosts if config.getboolean(host, "is_default", fallback=False) is True),
80
+ hosts[0],
81
+ )
82
+ if first_default_host == "localhost":
83
+ return LOCALHOST
84
+
85
+ return f"https://{first_default_host}.canvasmedical.com"
86
+
87
+
88
+ def request_api_token(host: str, api_client_credentials: str) -> dict:
89
+ """Request an api token using the provided client_id and client_secret."""
90
+ grant_type = "grant_type=client_credentials"
91
+ scope = "scope=system/Plugins.*"
92
+
93
+ http = Http()
94
+ token_response = http.post(
95
+ f"{host}/auth/token/",
96
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
97
+ data=f"{grant_type}&{scope}&{api_client_credentials}",
98
+ )
99
+ if token_response.status_code != requests.codes.ok:
100
+ raise Exception(f"Unable to get a valid access token from the given host '{host}'")
101
+ return token_response.json()
102
+
103
+
104
+ def get_or_request_api_token(host: str | None = None) -> str:
105
+ """Returns an existing stored token if it has not expired, or requests a new one."""
106
+ if not (host := get_default_host(host)):
107
+ raise Exception(
108
+ f"Please specify a host or add one to the configuration file at '{CONFIG_PATH}'"
109
+ )
110
+
111
+ token = get_token(host)
112
+
113
+ if token:
114
+ return token
115
+
116
+ api_client_credentials = get_api_client_credentials(host)
117
+
118
+ if not (token_response := request_api_token(host, api_client_credentials)):
119
+ raise Exception(f"A token could not be acquired from the given host '{host}'")
120
+
121
+ token_expiration_date = datetime.now() + timedelta(seconds=token_response["expires_in"])
122
+ if token_expiration_date <= datetime.now():
123
+ raise Exception(f"A valid token could not be acquired from the given host '{host}'")
124
+
125
+ new_token = token_response["access_token"]
126
+ set_token(host, new_token, token_expiration_date)
127
+ return new_token
@@ -0,0 +1,3 @@
1
+ from canvas_cli.apps.emit.emit import emit
2
+
3
+ __all__ = ("emit",)
@@ -0,0 +1,66 @@
1
+ import json
2
+ import random
3
+ from pathlib import Path
4
+ from typing import Annotated
5
+
6
+ import grpc
7
+ import typer
8
+
9
+ from canvas_generated.messages.events_pb2 import Event as PluginRunnerEvent
10
+ from canvas_generated.services.plugin_runner_pb2_grpc import PluginRunnerStub
11
+
12
+
13
+ def emit(
14
+ event_fixture: str,
15
+ plugin_runner_port: Annotated[
16
+ str, typer.Option(help="Port of your locally running plugin runner")
17
+ ] = "50051",
18
+ ) -> None:
19
+ """
20
+ Send an event fixture to your locally running plugin-runner process, and print any resultant effects.
21
+
22
+ Valid fixture files are newline-delimited JSON, with each containing the keys `EventType`, `target`, and `context`. Some fixture files are included in the canvas-plugins repo.
23
+ """
24
+ # If an event fixture file exists at the specified path, use it.
25
+ # Otherwise, see if it represents an event that we have a Canvas-provided
26
+ # fixture for and use that.
27
+ event_fixture_path = Path(event_fixture)
28
+
29
+ if not event_fixture_path.exists():
30
+ candidate_built_in_fixture_path = (
31
+ Path(__file__).resolve().parent / "event_fixtures" / f"{event_fixture}.ndjson"
32
+ )
33
+ if candidate_built_in_fixture_path.exists():
34
+ event_fixture_path = candidate_built_in_fixture_path
35
+ else:
36
+ print(f"ERROR: No file found at location {event_fixture}.")
37
+ print(f"ERROR: No built-in fixture file found named {event_fixture}.ndjson.")
38
+ return
39
+
40
+ # Grab a random event from the fixture file ndjson
41
+ lines = event_fixture_path.read_text().splitlines()
42
+ myline = random.choice(lines)
43
+ event_data = json.loads(myline)
44
+ event = PluginRunnerEvent(
45
+ type=event_data["EventType"],
46
+ target=event_data["target"],
47
+ context=event_data["context"],
48
+ )
49
+ with grpc.insecure_channel(f"localhost:{plugin_runner_port}") as channel:
50
+ stub = PluginRunnerStub(channel)
51
+ responses = stub.HandleEvent(event)
52
+
53
+ at_least_one_effect = False
54
+ try:
55
+ for response in responses:
56
+ for effect in response.effects:
57
+ at_least_one_effect = True
58
+ print(effect)
59
+
60
+ if not at_least_one_effect:
61
+ print("SUCCESS: No effects returned.")
62
+ except grpc.RpcError as e:
63
+ if e.code() == grpc.StatusCode.UNAVAILABLE:
64
+ print(
65
+ f"ERROR: Couldn't make a connection to a plugin runner process at localhost:{plugin_runner_port}. Is it running?"
66
+ )
@@ -0,0 +1 @@
1
+ {"EventType": "ALLERGY_INTOLERANCE_CREATED", "target": "4bbdb87a-3f97-4374-81e6-1e8ce5d3c121", "context": ""}
@@ -0,0 +1 @@
1
+ {"EventType": "ALLERGY_INTOLERANCE_UPDATED", "target": "4bbdb87a-3f97-4374-81e6-1e8ce5d3c121", "context": ""}