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.
- canvas-0.77.0/.gitignore +20 -0
- canvas-0.77.0/PKG-INFO +225 -0
- canvas-0.77.0/README.md +186 -0
- canvas-0.77.0/canvas_cli/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/apps/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/apps/auth/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/apps/auth/storage.py +65 -0
- canvas-0.77.0/canvas_cli/apps/auth/utils.py +127 -0
- canvas-0.77.0/canvas_cli/apps/emit/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/emit.py +66 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ALLERGY_INTOLERANCE_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CANCELED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CHECKED_IN.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_NO_SHOWED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESCHEDULED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_RESTORED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/APPOINTMENT_UPDATED.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__CONDITION_SELECTED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_COMMIT.ndjson +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_ORIGINATE.ndjson +4 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__POST_UPDATE.ndjson +5 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_COMMIT.ndjson +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_ORIGINATE.ndjson +4 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ASSESS_COMMAND__PRE_UPDATE.ndjson +5 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_CREATED.ndjson +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/BILLING_LINE_ITEM_UPDATED.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_ASSESSED.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_CREATED.ndjson +4 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CONDITION_UPDATED.ndjson +5 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/CRON.ndjson +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_CREATED.ndjson +3 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/ENCOUNTER_UPDATED.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_STATEMENT_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/IMMUNIZATION_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/INTERVIEW_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/INTERVIEW_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/LAB_ORDER_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_LIST_ITEM_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_COMMIT.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__POST_UPDATE.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_COMMIT.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT_COMMAND__PRE_UPDATE.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/MEDICATION_STATEMENT__MEDICATION__POST_SEARCH.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PATIENT_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PATIENT_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__POST_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/PLAN_COMMAND__PRE_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_COMMIT.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__POST_UPDATE.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_COMMIT.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_ORIGINATE.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE_COMMAND__PRE_UPDATE.ndjson +2 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/QUESTIONNAIRE__QUESTIONNAIRE__POST_SEARCH.ndjson +4 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/SIMPLE_API_REQUEST.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_COMMENT_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_CREATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/TASK_UPDATED.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/UNKNOWN.ndjson +1 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_CREATED.ndjson +14 -0
- canvas-0.77.0/canvas_cli/apps/emit/event_fixtures/VITAL_SIGN_UPDATED.ndjson +364 -0
- canvas-0.77.0/canvas_cli/apps/logs/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/apps/logs/logs.py +65 -0
- canvas-0.77.0/canvas_cli/apps/plugin/__init__.py +23 -0
- canvas-0.77.0/canvas_cli/apps/plugin/plugin.py +619 -0
- canvas-0.77.0/canvas_cli/apps/run_plugins/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/apps/run_plugins/run_plugins.py +102 -0
- canvas-0.77.0/canvas_cli/main.py +86 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/cookiecutter.json +4 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/CANVAS_MANIFEST.json +33 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/README.md +11 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/applications/my_application.py +15 -0
- canvas-0.77.0/canvas_cli/templates/plugins/application/{{ cookiecutter.__project_slug }}/assets/python-logo.png +0 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/cookiecutter.json +5 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/pyproject.toml +16 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/test_models.py +63 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/CANVAS_MANIFEST.json +24 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/README.md +11 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/protocols/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/{{ cookiecutter.__package_name }}/protocols/my_protocol.py +55 -0
- canvas-0.77.0/canvas_cli/utils/__init__.py +0 -0
- canvas-0.77.0/canvas_cli/utils/context/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/utils/context/context.py +150 -0
- canvas-0.77.0/canvas_cli/utils/print/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/utils/print/print.py +46 -0
- canvas-0.77.0/canvas_cli/utils/urls/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/utils/urls/urls.py +27 -0
- canvas-0.77.0/canvas_cli/utils/validators/__init__.py +3 -0
- canvas-0.77.0/canvas_cli/utils/validators/manifest_schema.py +157 -0
- canvas-0.77.0/canvas_cli/utils/validators/validators.py +40 -0
- canvas-0.77.0/canvas_generated/messages/effects_pb2.py +28 -0
- canvas-0.77.0/canvas_generated/messages/effects_pb2.pyi +591 -0
- canvas-0.77.0/canvas_generated/messages/effects_pb2_grpc.py +4 -0
- canvas-0.77.0/canvas_generated/messages/events_pb2.py +31 -0
- canvas-0.77.0/canvas_generated/messages/events_pb2.pyi +1895 -0
- canvas-0.77.0/canvas_generated/messages/events_pb2_grpc.py +4 -0
- canvas-0.77.0/canvas_generated/messages/plugins_pb2.py +36 -0
- canvas-0.77.0/canvas_generated/messages/plugins_pb2.pyi +39 -0
- canvas-0.77.0/canvas_generated/messages/plugins_pb2_grpc.py +4 -0
- canvas-0.77.0/canvas_generated/services/plugin_runner_pb2.py +28 -0
- canvas-0.77.0/canvas_generated/services/plugin_runner_pb2.pyi +6 -0
- canvas-0.77.0/canvas_generated/services/plugin_runner_pb2_grpc.py +166 -0
- canvas-0.77.0/canvas_sdk/__init__.py +12 -0
- canvas-0.77.0/canvas_sdk/base.py +109 -0
- canvas-0.77.0/canvas_sdk/caching/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/caching/base.py +127 -0
- canvas-0.77.0/canvas_sdk/caching/client.py +26 -0
- canvas-0.77.0/canvas_sdk/caching/exceptions.py +21 -0
- canvas-0.77.0/canvas_sdk/caching/plugins.py +23 -0
- canvas-0.77.0/canvas_sdk/caching/utils.py +28 -0
- canvas-0.77.0/canvas_sdk/commands/__init__.py +73 -0
- canvas-0.77.0/canvas_sdk/commands/base.py +203 -0
- canvas-0.77.0/canvas_sdk/commands/commands/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/commands/commands/adjust_prescription.py +21 -0
- canvas-0.77.0/canvas_sdk/commands/commands/allergy.py +45 -0
- canvas-0.77.0/canvas_sdk/commands/commands/assess.py +44 -0
- canvas-0.77.0/canvas_sdk/commands/commands/change_medication.py +58 -0
- canvas-0.77.0/canvas_sdk/commands/commands/chart_section_review.py +23 -0
- canvas-0.77.0/canvas_sdk/commands/commands/close_goal.py +16 -0
- canvas-0.77.0/canvas_sdk/commands/commands/diagnose.py +22 -0
- canvas-0.77.0/canvas_sdk/commands/commands/exam.py +12 -0
- canvas-0.77.0/canvas_sdk/commands/commands/family_history.py +31 -0
- canvas-0.77.0/canvas_sdk/commands/commands/follow_up.py +74 -0
- canvas-0.77.0/canvas_sdk/commands/commands/goal.py +39 -0
- canvas-0.77.0/canvas_sdk/commands/commands/history_present_illness.py +13 -0
- canvas-0.77.0/canvas_sdk/commands/commands/imaging_order.py +43 -0
- canvas-0.77.0/canvas_sdk/commands/commands/immunization_statement.py +72 -0
- canvas-0.77.0/canvas_sdk/commands/commands/instruct.py +31 -0
- canvas-0.77.0/canvas_sdk/commands/commands/lab_order.py +105 -0
- canvas-0.77.0/canvas_sdk/commands/commands/medical_history.py +21 -0
- canvas-0.77.0/canvas_sdk/commands/commands/medication_statement.py +43 -0
- canvas-0.77.0/canvas_sdk/commands/commands/past_surgical_history.py +34 -0
- canvas-0.77.0/canvas_sdk/commands/commands/perform.py +33 -0
- canvas-0.77.0/canvas_sdk/commands/commands/plan.py +13 -0
- canvas-0.77.0/canvas_sdk/commands/commands/prescribe.py +222 -0
- canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/__init__.py +107 -0
- canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/question.py +145 -0
- canvas-0.77.0/canvas_sdk/commands/commands/questionnaire/toggle_questions.py +68 -0
- canvas-0.77.0/canvas_sdk/commands/commands/reason_for_visit.py +52 -0
- canvas-0.77.0/canvas_sdk/commands/commands/refer.py +53 -0
- canvas-0.77.0/canvas_sdk/commands/commands/refill.py +39 -0
- canvas-0.77.0/canvas_sdk/commands/commands/remove_allergy.py +20 -0
- canvas-0.77.0/canvas_sdk/commands/commands/resolve_condition.py +47 -0
- canvas-0.77.0/canvas_sdk/commands/commands/review_of_systems.py +12 -0
- canvas-0.77.0/canvas_sdk/commands/commands/stop_medication.py +19 -0
- canvas-0.77.0/canvas_sdk/commands/commands/structured_assessment.py +11 -0
- canvas-0.77.0/canvas_sdk/commands/commands/task.py +44 -0
- canvas-0.77.0/canvas_sdk/commands/commands/update_diagnosis.py +22 -0
- canvas-0.77.0/canvas_sdk/commands/commands/update_goal.py +40 -0
- canvas-0.77.0/canvas_sdk/commands/commands/vitals.py +56 -0
- canvas-0.77.0/canvas_sdk/commands/constants.py +60 -0
- canvas-0.77.0/canvas_sdk/effects/__init__.py +5 -0
- canvas-0.77.0/canvas_sdk/effects/appointments_metadata/__init__.py +13 -0
- canvas-0.77.0/canvas_sdk/effects/appointments_metadata/appointments_metadata_create_form.py +12 -0
- canvas-0.77.0/canvas_sdk/effects/appointments_metadata/base.py +30 -0
- canvas-0.77.0/canvas_sdk/effects/banner_alert/__init__.py +4 -0
- canvas-0.77.0/canvas_sdk/effects/banner_alert/add_banner_alert.py +64 -0
- canvas-0.77.0/canvas_sdk/effects/banner_alert/remove_banner_alert.py +24 -0
- canvas-0.77.0/canvas_sdk/effects/base.py +35 -0
- canvas-0.77.0/canvas_sdk/effects/batch_originate.py +22 -0
- canvas-0.77.0/canvas_sdk/effects/billing_line_item/__init__.py +15 -0
- canvas-0.77.0/canvas_sdk/effects/billing_line_item/add_billing_line_item.py +41 -0
- canvas-0.77.0/canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +25 -0
- canvas-0.77.0/canvas_sdk/effects/billing_line_item/update_billing_line_item.py +47 -0
- canvas-0.77.0/canvas_sdk/effects/calendar/__init__.py +4 -0
- canvas-0.77.0/canvas_sdk/effects/calendar/create_calendar.py +40 -0
- canvas-0.77.0/canvas_sdk/effects/calendar/create_event.py +43 -0
- canvas-0.77.0/canvas_sdk/effects/claim_label.py +93 -0
- canvas-0.77.0/canvas_sdk/effects/claim_line_item.py +47 -0
- canvas-0.77.0/canvas_sdk/effects/claim_queue.py +49 -0
- canvas-0.77.0/canvas_sdk/effects/compound_medications/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/effects/compound_medications/compound_medication.py +275 -0
- canvas-0.77.0/canvas_sdk/effects/fax/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/effects/fax/base.py +77 -0
- canvas-0.77.0/canvas_sdk/effects/fax/note.py +42 -0
- canvas-0.77.0/canvas_sdk/effects/form.py +69 -0
- canvas-0.77.0/canvas_sdk/effects/generate_full_chart_pdf.py +56 -0
- canvas-0.77.0/canvas_sdk/effects/group.py +20 -0
- canvas-0.77.0/canvas_sdk/effects/launch_modal.py +46 -0
- canvas-0.77.0/canvas_sdk/effects/metadata.py +40 -0
- canvas-0.77.0/canvas_sdk/effects/note/__init__.py +17 -0
- canvas-0.77.0/canvas_sdk/effects/note/appointment.py +359 -0
- canvas-0.77.0/canvas_sdk/effects/note/base.py +260 -0
- canvas-0.77.0/canvas_sdk/effects/note/message.py +131 -0
- canvas-0.77.0/canvas_sdk/effects/note/note.py +186 -0
- canvas-0.77.0/canvas_sdk/effects/panel_configuration.py +90 -0
- canvas-0.77.0/canvas_sdk/effects/patient/__init__.py +25 -0
- canvas-0.77.0/canvas_sdk/effects/patient/base.py +283 -0
- canvas-0.77.0/canvas_sdk/effects/patient/create_patient_external_identifier.py +40 -0
- canvas-0.77.0/canvas_sdk/effects/patient/create_patient_preferred_pharmacies.py +70 -0
- canvas-0.77.0/canvas_sdk/effects/patient_chart_group.py +30 -0
- canvas-0.77.0/canvas_sdk/effects/patient_chart_summary_configuration.py +43 -0
- canvas-0.77.0/canvas_sdk/effects/patient_metadata/__init__.py +13 -0
- canvas-0.77.0/canvas_sdk/effects/patient_metadata/base.py +32 -0
- canvas-0.77.0/canvas_sdk/effects/patient_metadata/patient_metadata_create_form.py +12 -0
- canvas-0.77.0/canvas_sdk/effects/patient_portal/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/effects/patient_portal/application_configuration.py +25 -0
- canvas-0.77.0/canvas_sdk/effects/patient_portal/form_result.py +34 -0
- canvas-0.77.0/canvas_sdk/effects/patient_portal_menu_configuration.py +39 -0
- canvas-0.77.0/canvas_sdk/effects/patient_profile_configuration.py +48 -0
- canvas-0.77.0/canvas_sdk/effects/payment_processor.py +137 -0
- canvas-0.77.0/canvas_sdk/effects/protocol_card/__init__.py +6 -0
- canvas-0.77.0/canvas_sdk/effects/protocol_card/protocol_card.py +103 -0
- canvas-0.77.0/canvas_sdk/effects/questionnaire_result.py +32 -0
- canvas-0.77.0/canvas_sdk/effects/send_contact_verification.py +42 -0
- canvas-0.77.0/canvas_sdk/effects/send_invite.py +46 -0
- canvas-0.77.0/canvas_sdk/effects/show_button.py +32 -0
- canvas-0.77.0/canvas_sdk/effects/simple_api.py +151 -0
- canvas-0.77.0/canvas_sdk/effects/surescripts/__init__.py +11 -0
- canvas-0.77.0/canvas_sdk/effects/surescripts/surescripts_messages.py +100 -0
- canvas-0.77.0/canvas_sdk/effects/task/__init__.py +9 -0
- canvas-0.77.0/canvas_sdk/effects/task/task.py +178 -0
- canvas-0.77.0/canvas_sdk/effects/update_user.py +81 -0
- canvas-0.77.0/canvas_sdk/effects/widgets/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/effects/widgets/portal_widget.py +79 -0
- canvas-0.77.0/canvas_sdk/events/__init__.py +11 -0
- canvas-0.77.0/canvas_sdk/events/base.py +66 -0
- canvas-0.77.0/canvas_sdk/handlers/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/handlers/action_button.py +86 -0
- canvas-0.77.0/canvas_sdk/handlers/application.py +44 -0
- canvas-0.77.0/canvas_sdk/handlers/base.py +62 -0
- canvas-0.77.0/canvas_sdk/handlers/cron_task.py +38 -0
- canvas-0.77.0/canvas_sdk/handlers/payment_processors/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/handlers/payment_processors/base.py +93 -0
- canvas-0.77.0/canvas_sdk/handlers/payment_processors/card.py +200 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/__init__.py +29 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/api.py +539 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/exceptions.py +49 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/security.py +265 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/tools.py +124 -0
- canvas-0.77.0/canvas_sdk/handlers/simple_api/websocket.py +79 -0
- canvas-0.77.0/canvas_sdk/handlers/utils.py +14 -0
- canvas-0.77.0/canvas_sdk/protocols/__init__.py +4 -0
- canvas-0.77.0/canvas_sdk/protocols/base.py +14 -0
- canvas-0.77.0/canvas_sdk/protocols/clinical_quality_measure.py +137 -0
- canvas-0.77.0/canvas_sdk/protocols/timeframe.py +42 -0
- canvas-0.77.0/canvas_sdk/questionnaires/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/questionnaires/utils.py +125 -0
- canvas-0.77.0/canvas_sdk/templates/__init__.py +3 -0
- canvas-0.77.0/canvas_sdk/templates/utils.py +57 -0
- canvas-0.77.0/canvas_sdk/test_utils/__init__.py +0 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/__init__.py +69 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/claim.py +53 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/claim_diagnosis_code.py +16 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/facility.py +21 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/medication_history.py +75 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/note.py +37 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/organization.py +20 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/patient.py +51 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/practicelocation.py +34 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/protocol_current.py +44 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/staff.py +111 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/task.py +66 -0
- canvas-0.77.0/canvas_sdk/test_utils/factories/user.py +13 -0
- canvas-0.77.0/canvas_sdk/utils/__init__.py +9 -0
- canvas-0.77.0/canvas_sdk/utils/db.py +14 -0
- canvas-0.77.0/canvas_sdk/utils/http.py +364 -0
- canvas-0.77.0/canvas_sdk/utils/metrics.py +195 -0
- canvas-0.77.0/canvas_sdk/utils/plugins.py +66 -0
- canvas-0.77.0/canvas_sdk/v1/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/v1/apps.py +10 -0
- canvas-0.77.0/canvas_sdk/v1/data/__init__.py +254 -0
- canvas-0.77.0/canvas_sdk/v1/data/allergy_intolerance.py +77 -0
- canvas-0.77.0/canvas_sdk/v1/data/appointment.py +114 -0
- canvas-0.77.0/canvas_sdk/v1/data/assessment.py +36 -0
- canvas-0.77.0/canvas_sdk/v1/data/banner_alert.py +28 -0
- canvas-0.77.0/canvas_sdk/v1/data/base.py +264 -0
- canvas-0.77.0/canvas_sdk/v1/data/billing.py +84 -0
- canvas-0.77.0/canvas_sdk/v1/data/business_line.py +34 -0
- canvas-0.77.0/canvas_sdk/v1/data/care_team.py +58 -0
- canvas-0.77.0/canvas_sdk/v1/data/charge_description_master.py +29 -0
- canvas-0.77.0/canvas_sdk/v1/data/claim.py +381 -0
- canvas-0.77.0/canvas_sdk/v1/data/claim_diagnosis_code.py +19 -0
- canvas-0.77.0/canvas_sdk/v1/data/claim_line_item.py +136 -0
- canvas-0.77.0/canvas_sdk/v1/data/coding.py +19 -0
- canvas-0.77.0/canvas_sdk/v1/data/command.py +50 -0
- canvas-0.77.0/canvas_sdk/v1/data/common.py +174 -0
- canvas-0.77.0/canvas_sdk/v1/data/compound_medication.py +66 -0
- canvas-0.77.0/canvas_sdk/v1/data/condition.py +82 -0
- canvas-0.77.0/canvas_sdk/v1/data/coverage.py +310 -0
- canvas-0.77.0/canvas_sdk/v1/data/detected_issue.py +56 -0
- canvas-0.77.0/canvas_sdk/v1/data/device.py +38 -0
- canvas-0.77.0/canvas_sdk/v1/data/discount.py +18 -0
- canvas-0.77.0/canvas_sdk/v1/data/encounter.py +44 -0
- canvas-0.77.0/canvas_sdk/v1/data/facility.py +28 -0
- canvas-0.77.0/canvas_sdk/v1/data/fields.py +37 -0
- canvas-0.77.0/canvas_sdk/v1/data/goal.py +58 -0
- canvas-0.77.0/canvas_sdk/v1/data/imaging.py +115 -0
- canvas-0.77.0/canvas_sdk/v1/data/immunization.py +149 -0
- canvas-0.77.0/canvas_sdk/v1/data/invoice.py +62 -0
- canvas-0.77.0/canvas_sdk/v1/data/lab.py +323 -0
- canvas-0.77.0/canvas_sdk/v1/data/line_item_transaction.py +78 -0
- canvas-0.77.0/canvas_sdk/v1/data/medication.py +73 -0
- canvas-0.77.0/canvas_sdk/v1/data/medication_history.py +142 -0
- canvas-0.77.0/canvas_sdk/v1/data/medication_statement.py +41 -0
- canvas-0.77.0/canvas_sdk/v1/data/message.py +71 -0
- canvas-0.77.0/canvas_sdk/v1/data/note.py +235 -0
- canvas-0.77.0/canvas_sdk/v1/data/observation.py +103 -0
- canvas-0.77.0/canvas_sdk/v1/data/organization.py +30 -0
- canvas-0.77.0/canvas_sdk/v1/data/patient.py +317 -0
- canvas-0.77.0/canvas_sdk/v1/data/patient_consent.py +77 -0
- canvas-0.77.0/canvas_sdk/v1/data/payment_collection.py +31 -0
- canvas-0.77.0/canvas_sdk/v1/data/payor_specific_charge.py +26 -0
- canvas-0.77.0/canvas_sdk/v1/data/posting.py +211 -0
- canvas-0.77.0/canvas_sdk/v1/data/practicelocation.py +104 -0
- canvas-0.77.0/canvas_sdk/v1/data/protocol_current.py +23 -0
- canvas-0.77.0/canvas_sdk/v1/data/protocol_override.py +77 -0
- canvas-0.77.0/canvas_sdk/v1/data/protocol_result.py +46 -0
- canvas-0.77.0/canvas_sdk/v1/data/questionnaire.py +196 -0
- canvas-0.77.0/canvas_sdk/v1/data/reason_for_visit.py +19 -0
- canvas-0.77.0/canvas_sdk/v1/data/referral.py +88 -0
- canvas-0.77.0/canvas_sdk/v1/data/service_provider.py +54 -0
- canvas-0.77.0/canvas_sdk/v1/data/staff.py +257 -0
- canvas-0.77.0/canvas_sdk/v1/data/stop_medication_event.py +27 -0
- canvas-0.77.0/canvas_sdk/v1/data/task.py +131 -0
- canvas-0.77.0/canvas_sdk/v1/data/team.py +78 -0
- canvas-0.77.0/canvas_sdk/v1/data/user.py +32 -0
- canvas-0.77.0/canvas_sdk/v1/data/utils.py +37 -0
- canvas-0.77.0/canvas_sdk/v1/models.py +6 -0
- canvas-0.77.0/canvas_sdk/value_set/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/value_set/custom.py +1073 -0
- canvas-0.77.0/canvas_sdk/value_set/hcc2018.py +55372 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/__init__.py +1 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/adverse_event.py +36 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/allergy.py +242 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/assessment.py +227 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/communication.py +332 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/condition.py +40831 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/device.py +180 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/diagnostic_study.py +4982 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/encounter.py +2624 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/immunization.py +358 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/individual_characteristic.py +323 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/intervention.py +1362 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/laboratory_test.py +1279 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/medication.py +5225 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/physical_exam.py +212 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/procedure.py +4084 -0
- canvas-0.77.0/canvas_sdk/value_set/v2022/symptom.py +179 -0
- canvas-0.77.0/canvas_sdk/value_set/value_set.py +121 -0
- canvas-0.77.0/canvas_sdk/views/__init__.py +1 -0
- canvas-0.77.0/logger/__init__.py +5 -0
- canvas-0.77.0/logger/logger.py +75 -0
- canvas-0.77.0/plugin_runner/__init__.py +0 -0
- canvas-0.77.0/plugin_runner/allowed-module-imports.json +1537 -0
- canvas-0.77.0/plugin_runner/authentication.py +45 -0
- canvas-0.77.0/plugin_runner/aws_headers.py +77 -0
- canvas-0.77.0/plugin_runner/exceptions.py +18 -0
- canvas-0.77.0/plugin_runner/generate_allowed_imports.py +97 -0
- canvas-0.77.0/plugin_runner/installation.py +274 -0
- canvas-0.77.0/plugin_runner/load_all_plugins.py +199 -0
- canvas-0.77.0/plugin_runner/plugin_runner.py +779 -0
- canvas-0.77.0/plugin_runner/sandbox.py +958 -0
- canvas-0.77.0/protobufs/canvas_generated/messages/effects.proto +377 -0
- canvas-0.77.0/protobufs/canvas_generated/messages/events.proto +1235 -0
- canvas-0.77.0/protobufs/canvas_generated/messages/plugins.proto +24 -0
- canvas-0.77.0/protobufs/canvas_generated/services/plugin_runner.proto +16 -0
- canvas-0.77.0/pubsub/__init__.py +0 -0
- canvas-0.77.0/pubsub/pubsub.py +47 -0
- canvas-0.77.0/pyproject.toml +205 -0
- canvas-0.77.0/settings.py +196 -0
canvas-0.77.0/.gitignore
ADDED
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
|
+
[](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.
|
canvas-0.77.0/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
[](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,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,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": ""}
|