canvas 0.51.0__tar.gz → 0.53.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 (316) hide show
  1. {canvas-0.51.0 → canvas-0.53.0}/PKG-INFO +1 -1
  2. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/task/task.py +42 -4
  3. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/__init__.py +7 -1
  4. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/command.py +3 -0
  5. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/imaging.py +36 -7
  6. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/lab.py +8 -4
  7. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/note.py +9 -1
  8. canvas-0.53.0/canvas_sdk/v1/data/referral.py +102 -0
  9. canvas-0.53.0/canvas_sdk/v1/data/service_provider.py +54 -0
  10. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/staff.py +76 -1
  11. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/allowed-module-imports.json +13 -1
  12. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/sandbox.py +34 -1
  13. {canvas-0.51.0 → canvas-0.53.0}/pyproject.toml +1 -1
  14. {canvas-0.51.0 → canvas-0.53.0}/.gitignore +0 -0
  15. {canvas-0.51.0 → canvas-0.53.0}/README.md +0 -0
  16. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/__init__.py +0 -0
  17. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/__init__.py +0 -0
  18. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/auth/__init__.py +0 -0
  19. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/auth/storage.py +0 -0
  20. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/auth/utils.py +0 -0
  21. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/__init__.py +0 -0
  22. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/emit.py +0 -0
  23. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_CREATED.ndjson +0 -0
  24. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_UPDATED.ndjson +0 -0
  25. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CANCELED.ndjson +0 -0
  26. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CHECKED_IN.ndjson +0 -0
  27. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CREATED.ndjson +0 -0
  28. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_NO_SHOWED.ndjson +0 -0
  29. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESCHEDULED.ndjson +0 -0
  30. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESTORED.ndjson +0 -0
  31. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_UPDATED.ndjson +0 -0
  32. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__CONDITION_SELECTED.ndjson +0 -0
  33. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_COMMIT.ndjson +0 -0
  34. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_ORIGINATE.ndjson +0 -0
  35. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_UPDATE.ndjson +0 -0
  36. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_COMMIT.ndjson +0 -0
  37. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  38. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_UPDATE.ndjson +0 -0
  39. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_CREATED.ndjson +0 -0
  40. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_UPDATED.ndjson +0 -0
  41. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_ASSESSED.ndjson +0 -0
  42. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_CREATED.ndjson +0 -0
  43. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/CONDITION_UPDATED.ndjson +0 -0
  44. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/CRON.ndjson +0 -0
  45. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_CREATED.ndjson +0 -0
  46. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_UPDATED.ndjson +0 -0
  47. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_CREATED.ndjson +0 -0
  48. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_CREATED.ndjson +0 -0
  49. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_UPDATED.ndjson +0 -0
  50. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_UPDATED.ndjson +0 -0
  51. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/INTERVIEW_CREATED.ndjson +0 -0
  52. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/INTERVIEW_UPDATED.ndjson +0 -0
  53. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_CREATED.ndjson +0 -0
  54. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_UPDATED.ndjson +0 -0
  55. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_CREATED.ndjson +0 -0
  56. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_UPDATED.ndjson +0 -0
  57. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_COMMIT.ndjson +0 -0
  58. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_ORIGINATE.ndjson +0 -0
  59. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_UPDATE.ndjson +0 -0
  60. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_COMMIT.ndjson +0 -0
  61. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  62. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_UPDATE.ndjson +0 -0
  63. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT__MEDICATION__POST_SEARCH.ndjson +0 -0
  64. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/PATIENT_CREATED.ndjson +0 -0
  65. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/PATIENT_UPDATED.ndjson +0 -0
  66. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__POST_ORIGINATE.ndjson +0 -0
  67. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  68. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_COMMIT.ndjson +0 -0
  69. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_ORIGINATE.ndjson +0 -0
  70. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_UPDATE.ndjson +0 -0
  71. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_COMMIT.ndjson +0 -0
  72. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_ORIGINATE.ndjson +0 -0
  73. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_UPDATE.ndjson +0 -0
  74. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE__QUESTIONNAIRE__POST_SEARCH.ndjson +0 -0
  75. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/SIMPLE_API_REQUEST.ndjson +0 -0
  76. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/TASK_COMMENT_CREATED.ndjson +0 -0
  77. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/TASK_CREATED.ndjson +0 -0
  78. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/TASK_UPDATED.ndjson +0 -0
  79. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_CREATED.ndjson +0 -0
  80. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_UPDATED.ndjson +0 -0
  81. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/logs/__init__.py +0 -0
  82. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/logs/logs.py +0 -0
  83. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/plugin/__init__.py +0 -0
  84. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/plugin/plugin.py +0 -0
  85. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/run_plugins/__init__.py +0 -0
  86. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/apps/run_plugins/run_plugins.py +0 -0
  87. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/main.py +0 -0
  88. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/cookiecutter.json +0 -0
  89. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +0 -0
  90. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/README.md +0 -0
  91. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/__init__.py +0 -0
  92. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/my_application.py +0 -0
  93. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/assets/python-logo.png +0 -0
  94. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/default/cookiecutter.json +0 -0
  95. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +0 -0
  96. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/README.md +0 -0
  97. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/__init__.py +0 -0
  98. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/my_protocol.py +0 -0
  99. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/__init__.py +0 -0
  100. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/context/__init__.py +0 -0
  101. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/context/context.py +0 -0
  102. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/print/__init__.py +0 -0
  103. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/print/print.py +0 -0
  104. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/urls/__init__.py +0 -0
  105. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/urls/urls.py +0 -0
  106. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/validators/__init__.py +0 -0
  107. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/validators/manifest_schema.py +0 -0
  108. {canvas-0.51.0 → canvas-0.53.0}/canvas_cli/utils/validators/validators.py +0 -0
  109. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/effects_pb2.py +0 -0
  110. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/effects_pb2.pyi +0 -0
  111. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/effects_pb2_grpc.py +0 -0
  112. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/events_pb2.py +0 -0
  113. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/events_pb2.pyi +0 -0
  114. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/events_pb2_grpc.py +0 -0
  115. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/plugins_pb2.py +0 -0
  116. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/plugins_pb2.pyi +0 -0
  117. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/messages/plugins_pb2_grpc.py +0 -0
  118. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/services/plugin_runner_pb2.py +0 -0
  119. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/services/plugin_runner_pb2.pyi +0 -0
  120. {canvas-0.51.0 → canvas-0.53.0}/canvas_generated/services/plugin_runner_pb2_grpc.py +0 -0
  121. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/__init__.py +0 -0
  122. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/base.py +0 -0
  123. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/__init__.py +0 -0
  124. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/base.py +0 -0
  125. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/client.py +0 -0
  126. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/exceptions.py +0 -0
  127. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/plugins.py +0 -0
  128. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/caching/utils.py +0 -0
  129. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/__init__.py +0 -0
  130. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/base.py +0 -0
  131. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/__init__.py +0 -0
  132. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/adjust_prescription.py +0 -0
  133. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/allergy.py +0 -0
  134. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/assess.py +0 -0
  135. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/change_medication.py +0 -0
  136. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/chart_section_review.py +0 -0
  137. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/close_goal.py +0 -0
  138. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/diagnose.py +0 -0
  139. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/exam.py +0 -0
  140. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/family_history.py +0 -0
  141. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/follow_up.py +0 -0
  142. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/goal.py +0 -0
  143. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/history_present_illness.py +0 -0
  144. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/imaging_order.py +0 -0
  145. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/immunization_statement.py +0 -0
  146. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/instruct.py +0 -0
  147. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/lab_order.py +0 -0
  148. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/medical_history.py +0 -0
  149. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/medication_statement.py +0 -0
  150. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/past_surgical_history.py +0 -0
  151. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/perform.py +0 -0
  152. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/plan.py +0 -0
  153. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/prescribe.py +0 -0
  154. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/questionnaire/__init__.py +0 -0
  155. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/questionnaire/question.py +0 -0
  156. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/questionnaire/toggle_questions.py +0 -0
  157. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/reason_for_visit.py +0 -0
  158. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/refer.py +0 -0
  159. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/refill.py +0 -0
  160. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/remove_allergy.py +0 -0
  161. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/resolve_condition.py +0 -0
  162. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/review_of_systems.py +0 -0
  163. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/stop_medication.py +0 -0
  164. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/structured_assessment.py +0 -0
  165. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/task.py +0 -0
  166. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/update_diagnosis.py +0 -0
  167. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/update_goal.py +0 -0
  168. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/commands/vitals.py +0 -0
  169. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/commands/constants.py +0 -0
  170. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/__init__.py +0 -0
  171. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/banner_alert/__init__.py +0 -0
  172. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/banner_alert/add_banner_alert.py +0 -0
  173. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/banner_alert/remove_banner_alert.py +0 -0
  174. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/base.py +0 -0
  175. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/billing_line_item/__init__.py +0 -0
  176. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/billing_line_item/add_billing_line_item.py +0 -0
  177. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +0 -0
  178. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/billing_line_item/update_billing_line_item.py +0 -0
  179. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/compound_medications/__init__.py +0 -0
  180. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/compound_medications/compound_medication.py +0 -0
  181. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/launch_modal.py +0 -0
  182. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/note/__init__.py +0 -0
  183. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/note/appointment.py +0 -0
  184. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/note/base.py +0 -0
  185. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/note/message.py +0 -0
  186. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/note/note.py +0 -0
  187. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient/__init__.py +0 -0
  188. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient/base.py +0 -0
  189. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient/create_patient_external_identifier.py +0 -0
  190. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_chart_summary_configuration.py +0 -0
  191. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_metadata/__init__.py +0 -0
  192. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_metadata/base.py +0 -0
  193. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_metadata/patient_metadata_create_form.py +0 -0
  194. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_portal/__init__.py +0 -0
  195. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_portal/application_configuration.py +0 -0
  196. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_portal/form_result.py +0 -0
  197. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_portal_menu_configuration.py +0 -0
  198. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/patient_profile_configuration.py +0 -0
  199. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/protocol_card/__init__.py +0 -0
  200. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/protocol_card/protocol_card.py +0 -0
  201. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/questionnaire_result.py +0 -0
  202. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/send_invite.py +0 -0
  203. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/show_button.py +0 -0
  204. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/simple_api.py +0 -0
  205. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/surescripts/__init__.py +0 -0
  206. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/surescripts/surescripts_messages.py +0 -0
  207. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/task/__init__.py +0 -0
  208. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/update_user.py +0 -0
  209. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/widgets/__init__.py +0 -0
  210. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/effects/widgets/portal_widget.py +0 -0
  211. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/events/__init__.py +0 -0
  212. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/events/base.py +0 -0
  213. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/__init__.py +0 -0
  214. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/action_button.py +0 -0
  215. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/application.py +0 -0
  216. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/base.py +0 -0
  217. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/cron_task.py +0 -0
  218. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/__init__.py +0 -0
  219. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/api.py +0 -0
  220. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/exceptions.py +0 -0
  221. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/security.py +0 -0
  222. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/tools.py +0 -0
  223. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/handlers/simple_api/websocket.py +0 -0
  224. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/protocols/__init__.py +0 -0
  225. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/protocols/base.py +0 -0
  226. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/protocols/clinical_quality_measure.py +0 -0
  227. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/protocols/timeframe.py +0 -0
  228. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/questionnaires/__init__.py +0 -0
  229. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/questionnaires/utils.py +0 -0
  230. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/templates/__init__.py +0 -0
  231. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/templates/utils.py +0 -0
  232. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/utils/__init__.py +0 -0
  233. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/utils/db.py +0 -0
  234. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/utils/http.py +0 -0
  235. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/utils/metrics.py +0 -0
  236. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/utils/plugins.py +0 -0
  237. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/__init__.py +0 -0
  238. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/apps.py +0 -0
  239. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/allergy_intolerance.py +0 -0
  240. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/appointment.py +0 -0
  241. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/assessment.py +0 -0
  242. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/banner_alert.py +0 -0
  243. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/base.py +0 -0
  244. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/billing.py +0 -0
  245. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/business_line.py +0 -0
  246. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/care_team.py +0 -0
  247. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/charge_description_master.py +0 -0
  248. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/claim.py +0 -0
  249. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/claim_line_item.py +0 -0
  250. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/common.py +0 -0
  251. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/compound_medication.py +0 -0
  252. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/condition.py +0 -0
  253. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/coverage.py +0 -0
  254. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/detected_issue.py +0 -0
  255. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/device.py +0 -0
  256. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/discount.py +0 -0
  257. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/fields.py +0 -0
  258. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/invoice.py +0 -0
  259. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/line_item_transaction.py +0 -0
  260. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/medication.py +0 -0
  261. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/message.py +0 -0
  262. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/observation.py +0 -0
  263. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/organization.py +0 -0
  264. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/patient.py +0 -0
  265. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/patient_consent.py +0 -0
  266. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/payment_collection.py +0 -0
  267. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/payor_specific_charge.py +0 -0
  268. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/posting.py +0 -0
  269. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/practicelocation.py +0 -0
  270. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/protocol_override.py +0 -0
  271. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/questionnaire.py +0 -0
  272. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/reason_for_visit.py +0 -0
  273. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/task.py +0 -0
  274. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/team.py +0 -0
  275. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/user.py +0 -0
  276. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/data/utils.py +0 -0
  277. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/v1/models.py +0 -0
  278. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/__init__.py +0 -0
  279. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/custom.py +0 -0
  280. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/hcc2018.py +0 -0
  281. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/__init__.py +0 -0
  282. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/adverse_event.py +0 -0
  283. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/allergy.py +0 -0
  284. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/assessment.py +0 -0
  285. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/communication.py +0 -0
  286. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/condition.py +0 -0
  287. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/device.py +0 -0
  288. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/diagnostic_study.py +0 -0
  289. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/encounter.py +0 -0
  290. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/immunization.py +0 -0
  291. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/individual_characteristic.py +0 -0
  292. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/intervention.py +0 -0
  293. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/laboratory_test.py +0 -0
  294. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/medication.py +0 -0
  295. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/physical_exam.py +0 -0
  296. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/procedure.py +0 -0
  297. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/v2022/symptom.py +0 -0
  298. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/value_set/value_set.py +0 -0
  299. {canvas-0.51.0 → canvas-0.53.0}/canvas_sdk/views/__init__.py +0 -0
  300. {canvas-0.51.0 → canvas-0.53.0}/logger/__init__.py +0 -0
  301. {canvas-0.51.0 → canvas-0.53.0}/logger/logger.py +0 -0
  302. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/__init__.py +0 -0
  303. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/authentication.py +0 -0
  304. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/aws_headers.py +0 -0
  305. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/exceptions.py +0 -0
  306. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/generate_allowed_imports.py +0 -0
  307. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/installation.py +0 -0
  308. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/load_all_plugins.py +0 -0
  309. {canvas-0.51.0 → canvas-0.53.0}/plugin_runner/plugin_runner.py +0 -0
  310. {canvas-0.51.0 → canvas-0.53.0}/protobufs/canvas_generated/messages/effects.proto +0 -0
  311. {canvas-0.51.0 → canvas-0.53.0}/protobufs/canvas_generated/messages/events.proto +0 -0
  312. {canvas-0.51.0 → canvas-0.53.0}/protobufs/canvas_generated/messages/plugins.proto +0 -0
  313. {canvas-0.51.0 → canvas-0.53.0}/protobufs/canvas_generated/services/plugin_runner.proto +0 -0
  314. {canvas-0.51.0 → canvas-0.53.0}/pubsub/__init__.py +0 -0
  315. {canvas-0.51.0 → canvas-0.53.0}/pubsub/pubsub.py +0 -0
  316. {canvas-0.51.0 → canvas-0.53.0}/settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: canvas
3
- Version: 0.51.0
3
+ Version: 0.53.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
@@ -1,6 +1,9 @@
1
1
  from datetime import datetime
2
- from enum import Enum
3
- from typing import Any, cast
2
+ from enum import Enum, StrEnum
3
+ from typing import Any, Self, cast
4
+ from uuid import UUID
5
+
6
+ from pydantic import model_validator
4
7
 
5
8
  from canvas_sdk.effects.base import EffectType, _BaseEffect
6
9
 
@@ -18,10 +21,17 @@ class AddTask(_BaseEffect):
18
21
  An Effect that will create a Task in Canvas.
19
22
  """
20
23
 
24
+ class LinkableObjectType(StrEnum):
25
+ """Types of objects that can be linked to a Task."""
26
+
27
+ REFERRAL = "REFERRAL"
28
+ IMAGING = "IMAGING"
29
+
21
30
  class Meta:
22
31
  effect_type = EffectType.CREATE_TASK
23
32
  apply_required_fields = ("title",)
24
33
 
34
+ id: str | UUID | None = None
25
35
  assignee_id: str | None = None
26
36
  team_id: str | None = None
27
37
  patient_id: str | None = None
@@ -29,11 +39,29 @@ class AddTask(_BaseEffect):
29
39
  due: datetime | None = None
30
40
  status: TaskStatus = TaskStatus.OPEN
31
41
  labels: list[str] = []
42
+ linked_object_id: str | UUID | None = None
43
+ linked_object_type: LinkableObjectType | None = None
44
+ author_id: str | UUID | None = None
45
+
46
+ @model_validator(mode="after")
47
+ def check_needed_together_fields(self) -> Self:
48
+ """Check that linked_object_id and linked_object_type are set together."""
49
+ if self.linked_object_id is not None and self.linked_object_type is None:
50
+ raise ValueError(
51
+ "'linked_object_id' must be set with 'linked_object_type' if it is provided"
52
+ )
53
+ if self.linked_object_id is None and self.linked_object_type is not None:
54
+ raise ValueError(
55
+ "'linked_object_type' must be set with 'linked_object_id' if it is provided"
56
+ )
57
+
58
+ return self
32
59
 
33
60
  @property
34
61
  def values(self) -> dict[str, Any]:
35
62
  """The values for Task addition."""
36
63
  return {
64
+ "id": str(self.id) if self.id else None,
37
65
  "patient": {"id": self.patient_id},
38
66
  "due": self.due.isoformat() if self.due else None,
39
67
  "assignee": {"id": self.assignee_id},
@@ -41,6 +69,11 @@ class AddTask(_BaseEffect):
41
69
  "title": self.title,
42
70
  "status": self.status.value,
43
71
  "labels": self.labels,
72
+ "author_id": str(self.author_id) if self.author_id else None,
73
+ "linked_object": {
74
+ "id": str(self.linked_object_id) if self.linked_object_id else None,
75
+ "type": self.linked_object_type.value if self.linked_object_type else None,
76
+ },
44
77
  }
45
78
 
46
79
 
@@ -57,12 +90,17 @@ class AddTaskComment(_BaseEffect):
57
90
  )
58
91
 
59
92
  body: str | None = None
60
- task_id: str | None = None
93
+ task_id: str | UUID | None = None
94
+ author_id: str | UUID | None = None
61
95
 
62
96
  @property
63
97
  def values(self) -> dict[str, Any]:
64
98
  """The values for adding a task comment."""
65
- return {"task": {"id": self.task_id}, "body": self.body}
99
+ return {
100
+ "task": {"id": str(self.task_id) if self.task_id else None},
101
+ "body": self.body,
102
+ "author_id": str(self.author_id) if self.author_id else None,
103
+ }
66
104
 
67
105
 
68
106
  class UpdateTask(_BaseEffect):
@@ -80,7 +80,9 @@ from .questionnaire import (
80
80
  ResponseOptionSet,
81
81
  )
82
82
  from .reason_for_visit import ReasonForVisitSettingCoding
83
- from .staff import Staff, StaffAddress, StaffContactPoint, StaffPhoto
83
+ from .referral import Referral, ReferralReport
84
+ from .service_provider import ServiceProvider
85
+ from .staff import Staff, StaffAddress, StaffContactPoint, StaffPhoto, StaffRole
84
86
  from .task import Task, TaskComment, TaskLabel, TaskTaskLabel
85
87
  from .team import Team, TeamContactPoint
86
88
  from .user import CanvasUser
@@ -172,11 +174,15 @@ __all__ = __exports__ = (
172
174
  "Questionnaire",
173
175
  "QuestionnaireQuestionMap",
174
176
  "ReasonForVisitSettingCoding",
177
+ "Referral",
178
+ "ReferralReport",
175
179
  "ResponseOption",
176
180
  "ResponseOptionSet",
181
+ "ServiceProvider",
177
182
  "Staff",
178
183
  "StaffAddress",
179
184
  "StaffPhoto",
185
+ "StaffRole",
180
186
  "StaffContactPoint",
181
187
  "Task",
182
188
  "TaskComment",
@@ -40,6 +40,9 @@ class Command(IdentifiableModel):
40
40
  """
41
41
  # TODO: Is the anchor object type enough here, or do we need a mapping? The home-app model
42
42
  # names might not exactly match the plugins model names.
43
+ if not self.anchor_object_type or not self.anchor_object_dbid:
44
+ return None
45
+
43
46
  anchor_model = apps.get_model(
44
47
  app_label=self._meta.app_label, model_name=self.anchor_object_type
45
48
  )
@@ -1,3 +1,5 @@
1
+ import json
2
+
1
3
  from django.db import models
2
4
 
3
5
  from canvas_sdk.v1.data.base import IdentifiableModel
@@ -7,6 +9,7 @@ from canvas_sdk.v1.data.common import (
7
9
  ReviewPatientCommunicationMethod,
8
10
  ReviewStatus,
9
11
  )
12
+ from canvas_sdk.v1.data.task import Task
10
13
 
11
14
 
12
15
  class ImagingOrder(IdentifiableModel):
@@ -30,20 +33,39 @@ class ImagingOrder(IdentifiableModel):
30
33
  patient = models.ForeignKey(
31
34
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True
32
35
  )
33
- # TODO - uncomment when Note model is complete
34
- # note = models.ForeigneKey(Note, on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True)
36
+ note = models.ForeignKey(
37
+ "v1.Note", on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True
38
+ )
35
39
  imaging = models.CharField(max_length=1024)
36
- # TODO - uncomment when ServiceProvider model is complete
37
- # imaging_center = models.ForeignKey('v1.ServiceProvider', on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True)
40
+ imaging_center = models.ForeignKey(
41
+ "v1.ServiceProvider", on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True
42
+ )
38
43
  note_to_radiologist = models.CharField(max_length=1024)
39
44
  internal_comment = models.CharField(max_length=1024)
40
45
  status = models.CharField(choices=OrderStatus.choices, max_length=30)
41
46
  date_time_ordered = models.DateTimeField()
42
47
  priority = models.CharField(max_length=255)
43
- # TODO - uncomment when Staff model is complete
44
- # ordering_provider = models.ForeignKey('v1.Staff', on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True)
48
+ ordering_provider = models.ForeignKey(
49
+ "v1.Staff", on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True
50
+ )
45
51
  delegated = models.BooleanField(default=False)
46
52
 
53
+ task_ids = models.CharField(max_length=1024)
54
+
55
+ def get_task_objects(self) -> "models.QuerySet[Task]":
56
+ """Convert task IDs to Task objects."""
57
+ if self.task_ids:
58
+ task_ids = (
59
+ json.loads(self.task_ids) if isinstance(self.task_ids, str) else self.task_ids
60
+ )
61
+ return Task.objects.filter(id__in=task_ids)
62
+ return Task.objects.none()
63
+
64
+ @property
65
+ def task_list(self) -> list[Task]:
66
+ """Convenience property to get task objects."""
67
+ return list(self.get_task_objects())
68
+
47
69
 
48
70
  class ImagingReview(IdentifiableModel):
49
71
  """Model to read ImagingReview data."""
@@ -97,7 +119,14 @@ class ImagingReport(IdentifiableModel):
97
119
  patient = models.ForeignKey(
98
120
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="imaging_results", null=True
99
121
  )
100
- order = models.ForeignKey(ImagingOrder, on_delete=models.DO_NOTHING, null=True)
122
+ order = models.ForeignKey(
123
+ ImagingOrder,
124
+ on_delete=models.DO_NOTHING,
125
+ related_name="results",
126
+ default=None,
127
+ blank=True,
128
+ null=True,
129
+ )
101
130
  source = models.CharField(choices=ImagingReportSource.choices, max_length=18)
102
131
  name = models.CharField(max_length=255)
103
132
  result_date = models.DateField()
@@ -208,8 +208,8 @@ class LabOrder(IdentifiableModel):
208
208
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="lab_orders", null=True
209
209
  )
210
210
  ontology_lab_partner = models.CharField(max_length=128)
211
- # TODO - uncomment when the Note model is finished
212
- # note = models.ForeignKey("Note", on_delete=models.DO_NOTHING, null=True)
211
+
212
+ note = models.ForeignKey("v1.Note", on_delete=models.DO_NOTHING, null=True)
213
213
  comment = models.CharField(max_length=128)
214
214
  requisition_number = models.CharField(max_length=32)
215
215
  is_patient_bill = models.BooleanField(null=True)
@@ -224,8 +224,10 @@ class LabOrder(IdentifiableModel):
224
224
  )
225
225
  courtesy_copy_number = models.CharField(max_length=32)
226
226
  courtesy_copy_text = models.CharField(max_length=64)
227
- ordering_provider = models.ForeignKey(Staff, on_delete=models.DO_NOTHING, null=True)
228
- parent_order = models.ForeignKey("LabOrder", on_delete=models.DO_NOTHING, null=True)
227
+ ordering_provider = models.ForeignKey(
228
+ Staff, on_delete=models.DO_NOTHING, related_name="lab_orders", null=True
229
+ )
230
+ parent_order = models.ForeignKey("v1.LabOrder", on_delete=models.DO_NOTHING, null=True)
229
231
  healthgorilla_id = models.CharField(max_length=40)
230
232
  manual_processing_status = models.CharField(
231
233
  choices=ManualProcessingStatus.choices, null=True, max_length=16
@@ -233,6 +235,8 @@ class LabOrder(IdentifiableModel):
233
235
  manual_processing_comment = models.TextField(null=True)
234
236
  labcorp_abn_url = models.URLField()
235
237
 
238
+ reports = models.ManyToManyField("v1.LabReport", through="v1.LabTest")
239
+
236
240
 
237
241
  class LabOrderReason(Model):
238
242
  """A class representing a lab order reason."""
@@ -2,6 +2,7 @@ from django.contrib.postgres.fields import ArrayField
2
2
  from django.db import models
3
3
 
4
4
  from canvas_sdk.v1.data.base import IdentifiableModel
5
+ from canvas_sdk.v1.data.claim import Claim
5
6
 
6
7
 
7
8
  class NoteTypeCategories(models.TextChoices):
@@ -183,6 +184,13 @@ class Note(IdentifiableModel):
183
184
  datetime_of_service = models.DateTimeField()
184
185
  place_of_service = models.CharField(max_length=255)
185
186
 
187
+ def get_claim(self) -> Claim | None:
188
+ """
189
+ Get the most recent claim for this note.
190
+ Returns the latest claim ordered by created date, or None if no claims exist.
191
+ """
192
+ return self.claims.order_by("-created").first()
193
+
186
194
 
187
195
  class NoteStateChangeEvent(IdentifiableModel):
188
196
  """NoteStateChangeEvent."""
@@ -209,7 +217,7 @@ class CurrentNoteStateEvent(IdentifiableModel):
209
217
  db_table = "canvas_sdk_data_current_note_state_001"
210
218
 
211
219
  state = models.CharField(choices=NoteStates.choices, max_length=3)
212
- note = models.ForeignKey("v1.Note", on_delete=models.DO_NOTHING, related_name="+")
220
+ note = models.ForeignKey("v1.Note", on_delete=models.DO_NOTHING, related_name="current_state")
213
221
 
214
222
  def editable(self) -> bool:
215
223
  """Returns a boolean to indicate if the related note can be edited."""
@@ -0,0 +1,102 @@
1
+ import json
2
+
3
+ from django.db import models
4
+
5
+ from canvas_sdk.v1.data.base import IdentifiableModel
6
+ from canvas_sdk.v1.data.task import Task
7
+
8
+
9
+ class Referral(IdentifiableModel):
10
+ """Referral."""
11
+
12
+ class Meta:
13
+ db_table = "canvas_sdk_data_api_referral_001"
14
+
15
+ created = models.DateTimeField()
16
+ modified = models.DateTimeField()
17
+ originator = models.ForeignKey(
18
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
19
+ )
20
+ deleted = models.BooleanField()
21
+ committer = models.ForeignKey(
22
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
23
+ )
24
+ entered_in_error = models.ForeignKey(
25
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
26
+ )
27
+ patient = models.ForeignKey("v1.Patient", on_delete=models.DO_NOTHING)
28
+ note = models.ForeignKey("v1.Note", on_delete=models.DO_NOTHING)
29
+ service_provider = models.ForeignKey(
30
+ "v1.ServiceProvider",
31
+ on_delete=models.CASCADE,
32
+ related_name="referrals",
33
+ null=True,
34
+ blank=True,
35
+ )
36
+ assessments = models.ManyToManyField("v1.Assessment", related_name="referrals", blank=True)
37
+ clinical_question = models.CharField(max_length=50)
38
+ priority = models.CharField(max_length=255)
39
+ include_visit_note = models.BooleanField()
40
+ notes = models.TextField()
41
+ date_referred = models.DateTimeField()
42
+ forwarded = models.BooleanField()
43
+ internal_comment = models.TextField()
44
+ internal_task_comment = models.OneToOneField(
45
+ "v1.TaskComment", on_delete=models.SET_NULL, null=True, related_name="referral"
46
+ )
47
+ ignored = models.BooleanField()
48
+
49
+ task_ids = models.CharField(max_length=1024)
50
+
51
+ def get_task_objects(self) -> "models.QuerySet[Task]":
52
+ """Convert task IDs to Task objects."""
53
+ if self.task_ids:
54
+ task_ids = (
55
+ json.loads(self.task_ids) if isinstance(self.task_ids, str) else self.task_ids
56
+ )
57
+ return Task.objects.filter(id__in=task_ids)
58
+ return Task.objects.none()
59
+
60
+ @property
61
+ def task_list(self) -> list[Task]:
62
+ """Convenience property to get task objects."""
63
+ return list(self.get_task_objects())
64
+
65
+ def __str__(self) -> str:
66
+ return f"Referral {self.id}"
67
+
68
+
69
+ class ReferralReport(IdentifiableModel):
70
+ """ReferralReport."""
71
+
72
+ class Meta:
73
+ db_table = "canvas_sdk_data_api_referralreport_001"
74
+
75
+ created = models.DateTimeField(auto_now_add=True)
76
+ modified = models.DateTimeField(auto_now=True)
77
+ originator = models.ForeignKey(
78
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
79
+ )
80
+
81
+ review_mode = models.CharField(max_length=2)
82
+ assigned_by = models.ForeignKey(
83
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
84
+ )
85
+ junked = models.BooleanField()
86
+ requires_signature = models.BooleanField()
87
+ assigned_date = models.DateTimeField(null=True)
88
+ team_assigned_date = models.DateTimeField(null=True)
89
+ team = models.ForeignKey("v1.Team", on_delete=models.DO_NOTHING, null=True)
90
+ patient = models.ForeignKey(
91
+ "v1.Patient", on_delete=models.DO_NOTHING, related_name="referral_reports"
92
+ )
93
+ referral = models.ForeignKey(
94
+ Referral, on_delete=models.DO_NOTHING, related_name="reports", null=True
95
+ )
96
+ specialty = models.CharField(max_length=250)
97
+ original_date = models.DateField(null=True)
98
+ comment = models.TextField()
99
+ priority = models.BooleanField(default=False)
100
+
101
+
102
+ __exports__ = ("Referral", "ReferralReport")
@@ -0,0 +1,54 @@
1
+ from functools import cached_property
2
+
3
+ from django.db import models
4
+
5
+ from canvas_sdk.v1.data.base import IdentifiableModel
6
+
7
+
8
+ class ServiceProvider(IdentifiableModel):
9
+ """ServiceProvider."""
10
+
11
+ class Meta:
12
+ db_table = "canvas_sdk_data_data_integration_serviceprovider_001"
13
+
14
+ first_name = models.CharField(max_length=512)
15
+ # organizations won't have a last name
16
+ last_name = models.CharField(max_length=512, default="", blank=True)
17
+ business_fax = models.CharField(max_length=512, null=True, blank=True)
18
+ business_phone = models.CharField(max_length=512, null=True, blank=True)
19
+ business_address = models.CharField(max_length=512, null=True, blank=True)
20
+ specialty = models.CharField(max_length=512)
21
+ practice_name = models.CharField(max_length=512, null=True, blank=True)
22
+ notes = models.TextField(default="", null=True, blank=True)
23
+
24
+ @property
25
+ def full_name(self) -> str:
26
+ """Service provider full name."""
27
+ return f"{self.first_name} {self.last_name}"
28
+
29
+ @cached_property
30
+ def full_name_and_specialty(self) -> str:
31
+ """Service provider full name and specialty."""
32
+ name_components: list[str] = []
33
+
34
+ # Note 1: if firstName is (TBD) then insert at the end instead of the beginning
35
+ if self.first_name != "(TBD)":
36
+ name_components.append(self.first_name)
37
+
38
+ if self.first_name != self.last_name:
39
+ name_components.append(self.last_name)
40
+
41
+ if self.practice_name and self.practice_name != "(TBD)":
42
+ name_components.append(f"({self.practice_name}),")
43
+
44
+ if self.specialty not in [self.first_name, self.last_name, self.practice_name]:
45
+ name_components.append(self.specialty)
46
+
47
+ # see Note 1
48
+ if self.first_name == "(TBD)":
49
+ name_components.append(self.first_name)
50
+
51
+ return " ".join(name_components)
52
+
53
+
54
+ __exports__ = ("ServiceProvider",)
@@ -1,5 +1,8 @@
1
+ from functools import cached_property
2
+
1
3
  from django.contrib.postgres.fields import ArrayField
2
4
  from django.db import models
5
+ from django.db.models.enums import TextChoices
3
6
  from timezone_utils.fields import TimeZoneField
4
7
 
5
8
  from canvas_sdk.v1.data.base import IdentifiableModel, Model
@@ -82,6 +85,47 @@ class Staff(Model):
82
85
  photo = self.photos.first()
83
86
  return photo.url if photo else "https://d3hn0m4rbsz438.cloudfront.net/avatar1.png"
84
87
 
88
+ @cached_property
89
+ def full_name(self) -> str:
90
+ """Return Staff's first + last name."""
91
+ return f"{self.first_name} {self.last_name}"
92
+
93
+ @cached_property
94
+ def top_clinical_role(self) -> "StaffRole | None":
95
+ """Returns the topmost clinical role to assist in determining privilege levels.
96
+
97
+ Returns:
98
+ StaffRole | None: the topmost clinical role of the staff member.
99
+ """
100
+ roles = [
101
+ role
102
+ for role in self.roles.all()
103
+ if role.domain in StaffRole.RoleDomain.clinical_domains()
104
+ ]
105
+
106
+ if not roles:
107
+ return None
108
+
109
+ return roles[0]
110
+
111
+ @cached_property
112
+ def top_role_abbreviation(self) -> str | None:
113
+ """Returns the abbreviation string for the topmost role that the Staff object has.
114
+
115
+ Returns:
116
+ Optional[str]: The abbreviation for the topmost role, if available.
117
+ """
118
+ return self.top_clinical_role.public_abbreviation if self.top_clinical_role else None
119
+
120
+ @cached_property
121
+ def credentialed_name(self) -> str:
122
+ """Returns the full name of the staff member, suffixed with their topmost credential.
123
+
124
+ Returns:
125
+ str: The credentialed full name of the staff member.
126
+ """
127
+ return " ".join(filter(bool, [self.full_name, self.top_role_abbreviation or ""]))
128
+
85
129
 
86
130
  class StaffContactPoint(IdentifiableModel):
87
131
  """StaffContactPoint."""
@@ -136,4 +180,35 @@ class StaffPhoto(Model):
136
180
  title = models.CharField(max_length=255, blank=True, default="")
137
181
 
138
182
 
139
- __exports__ = ("Staff", "StaffContactPoint", "StaffAddress", "StaffPhoto")
183
+ class StaffRole(Model):
184
+ """StaffRole."""
185
+
186
+ class Meta:
187
+ db_table = "canvas_sdk_data_api_staffrole_001"
188
+
189
+ class RoleDomain(TextChoices):
190
+ CLINICAL = "CLI", "Clinical"
191
+ ADMINISTRATIVE = "ADM", "Administrative"
192
+ HYBRID = "HYB", "Hybrid"
193
+
194
+ @staticmethod
195
+ def clinical_domains() -> list["StaffRole.RoleDomain"]:
196
+ """Return a list of clinical role domains."""
197
+ return [StaffRole.RoleDomain.CLINICAL, StaffRole.RoleDomain.HYBRID]
198
+
199
+ class RoleType(TextChoices):
200
+ NON_LICENSED = "NON-LICENSED", "Non-Licensed"
201
+ LICENSED = "LICENSED", "Licensed"
202
+ PROVIDER = "PROVIDER", "Provider"
203
+
204
+ staff = models.ForeignKey(Staff, on_delete=models.CASCADE, related_name="roles")
205
+ internal_code = models.CharField(max_length=10)
206
+ public_abbreviation = models.CharField(max_length=10, default="", blank=True)
207
+ domain = models.CharField(max_length=3, choices=RoleDomain.choices, db_index=True)
208
+ name = models.CharField(max_length=50)
209
+ domain_privilege_level = models.IntegerField(default=0)
210
+ permissions = models.JSONField(default=dict, blank=True, null=True)
211
+ role_type = models.CharField(max_length=50, choices=RoleType.choices, blank=True)
212
+
213
+
214
+ __exports__ = ("Staff", "StaffContactPoint", "StaffAddress", "StaffPhoto", "StaffRole")
@@ -563,12 +563,16 @@
563
563
  "Questionnaire",
564
564
  "QuestionnaireQuestionMap",
565
565
  "ReasonForVisitSettingCoding",
566
+ "Referral",
567
+ "ReferralReport",
566
568
  "ResponseOption",
567
569
  "ResponseOptionSet",
570
+ "ServiceProvider",
568
571
  "Staff",
569
572
  "StaffAddress",
570
573
  "StaffContactPoint",
571
574
  "StaffPhoto",
575
+ "StaffRole",
572
576
  "Task",
573
577
  "TaskComment",
574
578
  "TaskLabel",
@@ -796,11 +800,19 @@
796
800
  "canvas_sdk.v1.data.reason_for_visit": [
797
801
  "ReasonForVisitSettingCoding"
798
802
  ],
803
+ "canvas_sdk.v1.data.referral": [
804
+ "Referral",
805
+ "ReferralReport"
806
+ ],
807
+ "canvas_sdk.v1.data.service_provider": [
808
+ "ServiceProvider"
809
+ ],
799
810
  "canvas_sdk.v1.data.staff": [
800
811
  "Staff",
801
812
  "StaffAddress",
802
813
  "StaffContactPoint",
803
- "StaffPhoto"
814
+ "StaffPhoto",
815
+ "StaffRole"
804
816
  ],
805
817
  "canvas_sdk.v1.data.task": [
806
818
  "EventType",
@@ -4,6 +4,7 @@ import ast
4
4
  import builtins
5
5
  import importlib
6
6
  import json
7
+ import operator
7
8
  import sys
8
9
  import types
9
10
  from _ast import AnnAssign
@@ -196,6 +197,8 @@ THIRD_PARTY_MODULES = {
196
197
  "BigIntegerField",
197
198
  "Case",
198
199
  "CharField",
200
+ "Count",
201
+ "F",
199
202
  "IntegerField",
200
203
  "Model", # remove when hyperscribe no longer needs it
201
204
  "Q",
@@ -225,6 +228,7 @@ THIRD_PARTY_MODULES = {
225
228
  "conint",
226
229
  "constr",
227
230
  "Field",
231
+ "RootModel",
228
232
  "ValidationError",
229
233
  },
230
234
  "rapidfuzz": {
@@ -264,6 +268,34 @@ def _unrestricted(_ob: Any, *args: Any, **kwargs: Any) -> Any:
264
268
  return _ob
265
269
 
266
270
 
271
+ def _inplacevar(op: Any, val: Any, expr: Any) -> Any:
272
+ """
273
+ Apply the specified operation to the value and expression.
274
+
275
+ NOTE: Does not yet support += concatenation for sequences.
276
+ """
277
+ ops = {
278
+ "-=": operator.isub,
279
+ "@=": operator.imatmul,
280
+ "**=": operator.ipow,
281
+ "*=": operator.imul,
282
+ "//=": operator.ifloordiv,
283
+ "/=": operator.itruediv,
284
+ "&=": operator.iand,
285
+ "%=": operator.imod,
286
+ "^=": operator.ixor,
287
+ "+=": operator.iadd,
288
+ "<<=": operator.ilshift,
289
+ ">>=": operator.irshift,
290
+ "|=": operator.ior,
291
+ }
292
+
293
+ if op not in ops:
294
+ raise ValueError(f"Invalid inplace operation: {op}")
295
+
296
+ return ops[op](val, expr)
297
+
298
+
267
299
  def _apply(_ob: Any, *args: Any, **kwargs: Any) -> Any:
268
300
  """Call the bound method with args, support calling super().__init__()."""
269
301
  return _ob(*args, **kwargs)
@@ -614,6 +646,7 @@ class Sandbox:
614
646
  "dict": builtins.dict,
615
647
  "enumerate": builtins.enumerate,
616
648
  "filter": builtins.filter,
649
+ "getattr": self._safe_getattr,
617
650
  "hasattr": builtins.hasattr,
618
651
  "iter": builtins.iter,
619
652
  "list": builtins.list,
@@ -634,7 +667,7 @@ class Sandbox:
634
667
  "_getattr_": self._safe_getattr,
635
668
  "_getitem_": self._safe_getitem,
636
669
  "_getiter_": _unrestricted,
637
- "_inplacevar_": _unrestricted,
670
+ "_inplacevar_": _inplacevar,
638
671
  "_iter_unpack_sequence_": guarded_iter_unpack_sequence,
639
672
  "_print_": PrintCollector,
640
673
  "_unpack_sequence_": guarded_unpack_sequence,
@@ -57,7 +57,7 @@ license = "MIT"
57
57
  name = "canvas"
58
58
  readme = "README.md"
59
59
  requires-python = ">=3.11,<3.13"
60
- version = "0.51.0"
60
+ version = "0.53.0"
61
61
 
62
62
  [project.scripts]
63
63
  canvas = "canvas_cli.main:app"
File without changes
File without changes
File without changes