canvas 0.33.0__py3-none-any.whl → 0.34.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of canvas might be problematic. Click here for more details.
- {canvas-0.33.0.dist-info → canvas-0.34.0.dist-info}/METADATA +2 -1
- canvas-0.34.0.dist-info/RECORD +272 -0
- canvas_sdk/__init__.py +3 -0
- canvas_sdk/commands/__init__.py +1 -1
- canvas_sdk/commands/base.py +3 -0
- canvas_sdk/commands/commands/__init__.py +1 -0
- canvas_sdk/commands/commands/adjust_prescription.py +3 -0
- canvas_sdk/commands/commands/allergy.py +7 -0
- canvas_sdk/commands/commands/assess.py +2 -0
- canvas_sdk/commands/commands/close_goal.py +3 -0
- canvas_sdk/commands/commands/diagnose.py +3 -0
- canvas_sdk/commands/commands/exam.py +3 -0
- canvas_sdk/commands/commands/family_history.py +3 -0
- canvas_sdk/commands/commands/follow_up.py +3 -0
- canvas_sdk/commands/commands/goal.py +3 -0
- canvas_sdk/commands/commands/history_present_illness.py +3 -0
- canvas_sdk/commands/commands/imaging_order.py +3 -0
- canvas_sdk/commands/commands/instruct.py +3 -0
- canvas_sdk/commands/commands/lab_order.py +3 -0
- canvas_sdk/commands/commands/medical_history.py +3 -0
- canvas_sdk/commands/commands/medication_statement.py +2 -0
- canvas_sdk/commands/commands/past_surgical_history.py +3 -0
- canvas_sdk/commands/commands/perform.py +3 -0
- canvas_sdk/commands/commands/plan.py +3 -0
- canvas_sdk/commands/commands/prescribe.py +8 -0
- canvas_sdk/commands/commands/questionnaire/__init__.py +3 -13
- canvas_sdk/commands/commands/questionnaire/question.py +10 -0
- canvas_sdk/commands/commands/reason_for_visit.py +3 -0
- canvas_sdk/commands/commands/refer.py +3 -0
- canvas_sdk/commands/commands/refill.py +3 -0
- canvas_sdk/commands/commands/remove_allergy.py +3 -0
- canvas_sdk/commands/commands/resolve_condition.py +3 -0
- canvas_sdk/commands/commands/review_of_systems.py +3 -0
- canvas_sdk/commands/commands/stop_medication.py +3 -0
- canvas_sdk/commands/commands/structured_assessment.py +3 -0
- canvas_sdk/commands/commands/task.py +7 -0
- canvas_sdk/commands/commands/update_diagnosis.py +3 -0
- canvas_sdk/commands/commands/update_goal.py +3 -0
- canvas_sdk/commands/commands/vitals.py +3 -0
- canvas_sdk/commands/constants.py +8 -0
- canvas_sdk/effects/__init__.py +1 -1
- canvas_sdk/effects/banner_alert/__init__.py +1 -1
- canvas_sdk/effects/banner_alert/add_banner_alert.py +3 -0
- canvas_sdk/effects/banner_alert/remove_banner_alert.py +3 -0
- canvas_sdk/effects/base.py +7 -0
- canvas_sdk/effects/billing_line_item/__init__.py +5 -1
- canvas_sdk/effects/billing_line_item/add_billing_line_item.py +3 -0
- canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +3 -0
- canvas_sdk/effects/billing_line_item/update_billing_line_item.py +3 -0
- canvas_sdk/effects/launch_modal.py +3 -0
- canvas_sdk/effects/patient_chart_summary_configuration.py +3 -0
- canvas_sdk/effects/patient_portal/__init__.py +1 -0
- canvas_sdk/effects/patient_portal/application_configuration.py +3 -0
- canvas_sdk/effects/patient_portal/form_result.py +3 -0
- canvas_sdk/effects/patient_portal_menu_configuration.py +3 -0
- canvas_sdk/effects/patient_profile_configuration.py +5 -1
- canvas_sdk/effects/protocol_card/__init__.py +1 -1
- canvas_sdk/effects/protocol_card/protocol_card.py +6 -0
- canvas_sdk/effects/questionnaire_result.py +3 -0
- canvas_sdk/effects/send_invite.py +3 -0
- canvas_sdk/effects/show_button.py +3 -0
- canvas_sdk/effects/simple_api.py +9 -0
- canvas_sdk/effects/surescripts/__init__.py +2 -2
- canvas_sdk/effects/surescripts/surescripts_messages.py +7 -0
- canvas_sdk/effects/task/__init__.py +6 -1
- canvas_sdk/effects/task/task.py +8 -0
- canvas_sdk/effects/update_user.py +3 -0
- canvas_sdk/effects/widgets/__init__.py +1 -1
- canvas_sdk/effects/widgets/portal_widget.py +3 -0
- canvas_sdk/events/__init__.py +6 -1
- canvas_sdk/events/base.py +3 -0
- canvas_sdk/handlers/__init__.py +1 -1
- canvas_sdk/handlers/action_button.py +6 -0
- canvas_sdk/handlers/application.py +3 -0
- canvas_sdk/handlers/base.py +3 -0
- canvas_sdk/handlers/cron_task.py +3 -0
- canvas_sdk/handlers/simple_api/__init__.py +3 -2
- canvas_sdk/handlers/simple_api/api.py +26 -1
- canvas_sdk/handlers/simple_api/exceptions.py +10 -0
- canvas_sdk/handlers/simple_api/security.py +21 -5
- canvas_sdk/handlers/simple_api/tools.py +9 -0
- canvas_sdk/protocols/__init__.py +1 -1
- canvas_sdk/protocols/base.py +3 -0
- canvas_sdk/protocols/clinical_quality_measure.py +6 -1
- canvas_sdk/protocols/timeframe.py +3 -0
- canvas_sdk/questionnaires/__init__.py +1 -1
- canvas_sdk/questionnaires/utils.py +7 -0
- canvas_sdk/templates/__init__.py +1 -1
- canvas_sdk/templates/utils.py +3 -0
- canvas_sdk/utils/__init__.py +1 -1
- canvas_sdk/utils/http.py +94 -35
- canvas_sdk/utils/plugins.py +4 -0
- canvas_sdk/utils/stats.py +11 -0
- canvas_sdk/v1/__init__.py +1 -0
- canvas_sdk/v1/apps.py +3 -0
- canvas_sdk/v1/data/__init__.py +2 -2
- canvas_sdk/v1/data/allergy_intolerance.py +3 -0
- canvas_sdk/v1/data/appointment.py +7 -0
- canvas_sdk/v1/data/assessment.py +3 -0
- canvas_sdk/v1/data/banner_alert.py +3 -0
- canvas_sdk/v1/data/base.py +3 -0
- canvas_sdk/v1/data/billing.py +7 -0
- canvas_sdk/v1/data/care_team.py +7 -0
- canvas_sdk/v1/data/command.py +3 -0
- canvas_sdk/v1/data/common.py +18 -0
- canvas_sdk/v1/data/condition.py +7 -0
- canvas_sdk/v1/data/coverage.py +14 -0
- canvas_sdk/v1/data/detected_issue.py +3 -0
- canvas_sdk/v1/data/device.py +3 -0
- canvas_sdk/v1/data/imaging.py +7 -0
- canvas_sdk/v1/data/lab.py +16 -0
- canvas_sdk/v1/data/medication.py +3 -0
- canvas_sdk/v1/data/note.py +9 -0
- canvas_sdk/v1/data/observation.py +9 -0
- canvas_sdk/v1/data/organization.py +3 -0
- canvas_sdk/v1/data/patient.py +18 -2
- canvas_sdk/v1/data/practicelocation.py +7 -0
- canvas_sdk/v1/data/protocol_override.py +7 -0
- canvas_sdk/v1/data/questionnaire.py +16 -3
- canvas_sdk/v1/data/reason_for_visit.py +3 -0
- canvas_sdk/v1/data/staff.py +3 -0
- canvas_sdk/v1/data/task.py +12 -0
- canvas_sdk/v1/data/team.py +8 -1
- canvas_sdk/v1/data/user.py +3 -0
- canvas_sdk/v1/models.py +2 -0
- canvas_sdk/value_set/__init__.py +1 -0
- canvas_sdk/value_set/_utilities.py +16 -0
- canvas_sdk/value_set/custom.py +4 -0
- canvas_sdk/value_set/hcc2018.py +3 -0
- canvas_sdk/value_set/v2022/__init__.py +1 -0
- canvas_sdk/value_set/v2022/adverse_event.py +3 -0
- canvas_sdk/value_set/v2022/allergy.py +5 -0
- canvas_sdk/value_set/v2022/assessment.py +5 -0
- canvas_sdk/value_set/v2022/communication.py +5 -0
- canvas_sdk/value_set/v2022/condition.py +5 -0
- canvas_sdk/value_set/v2022/device.py +5 -0
- canvas_sdk/value_set/v2022/diagnostic_study.py +5 -0
- canvas_sdk/value_set/v2022/encounter.py +5 -0
- canvas_sdk/value_set/v2022/immunization.py +5 -0
- canvas_sdk/value_set/v2022/individual_characteristic.py +5 -0
- canvas_sdk/value_set/v2022/intervention.py +5 -0
- canvas_sdk/value_set/v2022/laboratory_test.py +5 -0
- canvas_sdk/value_set/v2022/medication.py +5 -0
- canvas_sdk/value_set/v2022/physical_exam.py +5 -0
- canvas_sdk/value_set/v2022/procedure.py +5 -0
- canvas_sdk/value_set/v2022/symptom.py +3 -0
- canvas_sdk/value_set/value_set.py +9 -0
- canvas_sdk/views/__init__.py +1 -0
- logger/__init__.py +2 -0
- logger/logger.py +3 -0
- plugin_runner/aws_headers.py +1 -1
- plugin_runner/load_all_plugins.py +202 -0
- plugin_runner/plugin_runner.py +21 -24
- plugin_runner/sandbox.py +497 -115
- settings.py +5 -2
- canvas-0.33.0.dist-info/RECORD +0 -366
- canvas_cli/apps/auth/tests.py +0 -155
- canvas_cli/apps/plugin/tests.py +0 -85
- canvas_cli/conftest.py +0 -28
- canvas_cli/tests.py +0 -217
- canvas_cli/utils/context/tests.py +0 -131
- canvas_cli/utils/print/tests.py +0 -69
- canvas_cli/utils/urls/tests.py +0 -12
- canvas_cli/utils/validators/tests.py +0 -37
- canvas_sdk/commands/tests/protocol/__init__.py +0 -0
- canvas_sdk/commands/tests/protocol/tests.py +0 -83
- canvas_sdk/commands/tests/schema/__init__.py +0 -0
- canvas_sdk/commands/tests/schema/tests.py +0 -108
- canvas_sdk/commands/tests/test_base_command.py +0 -81
- canvas_sdk/commands/tests/test_utils.py +0 -375
- canvas_sdk/commands/tests/unit/__init__.py +0 -0
- canvas_sdk/commands/tests/unit/tests.py +0 -278
- canvas_sdk/effects/banner_alert/tests.py +0 -288
- canvas_sdk/effects/protocol_card/tests.py +0 -191
- canvas_sdk/questionnaires/tests/__init__.py +0 -0
- canvas_sdk/questionnaires/tests/test_utils.py +0 -74
- canvas_sdk/templates/tests/__init__.py +0 -0
- canvas_sdk/templates/tests/test_utils.py +0 -43
- canvas_sdk/tests/__init__.py +0 -0
- canvas_sdk/tests/handlers/__init__.py +0 -0
- canvas_sdk/tests/handlers/test_simple_api.py +0 -1167
- canvas_sdk/utils/tests.py +0 -72
- canvas_sdk/value_set/tests/test_value_sets.py +0 -72
- plugin_runner/tests/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/example_plugin/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/example_plugin/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/CANVAS_MANIFEST.json +0 -38
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/README.md +0 -11
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/my_protocol.py +0 -33
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/__init__.py +0 -3
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/base.py +0 -6
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/__init__.py +0 -5
- plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/base.py +0 -4
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/CANVAS_MANIFEST.json +0 -52
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/README.md +0 -11
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/my_protocol.py +0 -39
- plugin_runner/tests/fixtures/plugins/test_load_questionnaire/questionnaires/example_questionnaire.yml +0 -61
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/base.py +0 -10
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/base.py +0 -10
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/base.py +0 -3
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/base.py +0 -6
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/base.py +0 -8
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/CANVAS_MANIFEST.json +0 -29
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/README.md +0 -12
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/base.py +0 -3
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/my_protocol.py +0 -18
- plugin_runner/tests/fixtures/plugins/test_render_template/CANVAS_MANIFEST.json +0 -47
- plugin_runner/tests/fixtures/plugins/test_render_template/README.md +0 -11
- plugin_runner/tests/fixtures/plugins/test_render_template/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_render_template/protocols/my_protocol.py +0 -43
- plugin_runner/tests/fixtures/plugins/test_render_template/templates/template.html +0 -10
- plugin_runner/tests/fixtures/plugins/test_simple_api/CANVAS_MANIFEST.json +0 -47
- plugin_runner/tests/fixtures/plugins/test_simple_api/README.md +0 -11
- plugin_runner/tests/fixtures/plugins/test_simple_api/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/my_protocol.py +0 -43
- plugin_runner/tests/test_application.py +0 -65
- plugin_runner/tests/test_plugin_installer.py +0 -127
- plugin_runner/tests/test_plugin_runner.py +0 -388
- plugin_runner/tests/test_sandbox.py +0 -137
- {canvas-0.33.0.dist-info → canvas-0.34.0.dist-info}/WHEEL +0 -0
- {canvas-0.33.0.dist-info → canvas-0.34.0.dist-info}/entry_points.txt +0 -0
canvas_sdk/v1/data/user.py
CHANGED
canvas_sdk/v1/models.py
CHANGED
canvas_sdk/value_set/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__exports__ = ()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from inspect import isclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from canvas_sdk.value_set.value_set import ValueSet
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_overrides(dictionary: dict[str, Any]) -> tuple:
|
|
8
|
+
"""
|
|
9
|
+
Return the keys that are ValueSets.
|
|
10
|
+
"""
|
|
11
|
+
return tuple(
|
|
12
|
+
key for key, value in dictionary.items() if isclass(value) and issubclass(value, ValueSet)
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__exports__ = ()
|
canvas_sdk/value_set/custom.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
1
2
|
from canvas_sdk.value_set.value_set import ValueSet
|
|
2
3
|
|
|
3
4
|
|
|
@@ -1055,3 +1056,6 @@ class DiabetesOtherClassConditionSuspect(ValueSet):
|
|
|
1055
1056
|
"L98498",
|
|
1056
1057
|
"L98499",
|
|
1057
1058
|
}
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
__exports__ = get_overrides(locals().copy())
|
canvas_sdk/value_set/hcc2018.py
CHANGED
|
@@ -55367,3 +55367,6 @@ class HCCConditions(ValueSet):
|
|
|
55367
55367
|
if icd10 in HCCConditions.LABELS:
|
|
55368
55368
|
return cast(float, HCCConditions.LABELS[icd10]["CommunityRAF"])
|
|
55369
55369
|
return 0
|
|
55370
|
+
|
|
55371
|
+
|
|
55372
|
+
__exports__ = ("HCCConditions",)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__exports__ = ()
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -230,3 +232,6 @@ class StatinAllergen(ValueSet):
|
|
|
230
232
|
SNOMEDCT = {
|
|
231
233
|
"372912004", # Substance with 3-hydroxy-3-methylglutaryl-coenzyme A reductase inhibitor mechanism of action (substance)
|
|
232
234
|
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -213,3 +215,6 @@ class HistoryOfHipFractureInParent(ValueSet):
|
|
|
213
215
|
"445121000124105", # Family history of paternal hip fracture (situation)
|
|
214
216
|
"445501000124107", # Family history of hip fracture in parent (situation)
|
|
215
217
|
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -323,3 +325,6 @@ class ConsultantReport(ValueSet):
|
|
|
323
325
|
"371531000", # Report of clinical encounter (record artifact)
|
|
324
326
|
"371545006", # Confirmatory consultation report (record artifact)
|
|
325
327
|
}
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -40652,3 +40654,6 @@ class UrinaryRetention(ValueSet):
|
|
|
40652
40654
|
"267064002", # Retention of urine (disorder)
|
|
40653
40655
|
"12245681000119103", # Postprocedural retention of urine (disorder)
|
|
40654
40656
|
}
|
|
40657
|
+
|
|
40658
|
+
|
|
40659
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -172,3 +174,6 @@ class CardiacPacer(ValueSet):
|
|
|
172
174
|
"360128001", # Intravenous triggered cardiac pacemaker system (physical object)
|
|
173
175
|
"424921004", # Permanent cardiac pacemaker, device (physical object)
|
|
174
176
|
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -4965,3 +4967,6 @@ class DexaDualEnergyXrayAbsorptiometry_BoneDensityForUrologyCare(ValueSet):
|
|
|
4965
4967
|
"38265-5", # DXA Radius and Ulna [T-score] Bone density
|
|
4966
4968
|
"38268-9", # DXA Skeletal system Views for bone density
|
|
4967
4969
|
}
|
|
4970
|
+
|
|
4971
|
+
|
|
4972
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -2562,3 +2564,6 @@ class HospitalServicesForUrologyCare(ValueSet):
|
|
|
2562
2564
|
"99283", # Emergency department visit for the evaluation and management of a patient, which requires these 3 key components: An expanded problem focused history; An expanded problem focused examination; and Medical decision making of moderate complexity. Counseling and/or coordination of care with other physicians, other qualified health care professionals, or agencies are provided consistent with the nature of the problem(s) and the patient's and/or family's needs. Usually, the presenting problem(s) are of moderate severity.
|
|
2563
2565
|
"99284", # Emergency department visit for the evaluation and management of a patient, which requires these 3 key components: A detailed history; A detailed examination; and Medical decision making of moderate complexity. Counseling and/or coordination of care with other physicians, other qualified health care professionals, or agencies are provided consistent with the nature of the problem(s) and the patient's and/or family's needs. Usually, the presenting problem(s) are of high severity, and require urgent evaluation by the physician, or other qualified health care professionals but do not pose an immediate significant threat to life or physiologic function.
|
|
2564
2566
|
}
|
|
2567
|
+
|
|
2568
|
+
|
|
2569
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -339,3 +341,6 @@ class PneumococcalPolysaccharide23Vaccine(ValueSet):
|
|
|
339
341
|
"33", # pneumococcal polysaccharide vaccine, 23 valent
|
|
340
342
|
"109", # pneumococcal vaccine, unspecified formulation
|
|
341
343
|
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -1330,3 +1332,6 @@ class ReferralsWhereWeightAssessmentMayOccur(ValueSet):
|
|
|
1330
1332
|
"408289007", # Refer to weight management program (procedure)
|
|
1331
1333
|
"416790000", # Referral for home physical therapy (procedure)
|
|
1332
1334
|
}
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -1248,3 +1250,6 @@ class HumanImmunodeficiencyVirusHivLaboratoryTestCodesAbAndAg(ValueSet):
|
|
|
1248
1250
|
"9669-3", # HIV 1 p66 Ab [Presence] in Serum by Immunoblot
|
|
1249
1251
|
"9821-0", # HIV 1 p24 Ag [Presence] in Serum
|
|
1250
1252
|
}
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -5128,3 +5130,6 @@ class MedicationsForBelowNormalBmi(ValueSet):
|
|
|
5128
5130
|
"860221", # megestrol acetate 40 MG Oral Tablet
|
|
5129
5131
|
"860225", # megestrol acetate 40 MG/ML Oral Suspension
|
|
5130
5132
|
}
|
|
5133
|
+
|
|
5134
|
+
|
|
5135
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -199,3 +201,6 @@ class BmiRatio(ValueSet):
|
|
|
199
201
|
LOINC = {
|
|
200
202
|
"39156-5", # Body mass index (BMI) [Ratio]
|
|
201
203
|
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from canvas_sdk.value_set._utilities import get_overrides
|
|
2
|
+
|
|
1
3
|
from ..value_set import ValueSet
|
|
2
4
|
|
|
3
5
|
|
|
@@ -4037,3 +4039,6 @@ class FluorideVarnishApplicationForChildren(ValueSet):
|
|
|
4037
4039
|
"234723000", # Topical application of fluoride - tooth (procedure)
|
|
4038
4040
|
"313042009", # Application of dental fluoride varnish (procedure)
|
|
4039
4041
|
}
|
|
4042
|
+
|
|
4043
|
+
|
|
4044
|
+
__exports__ = get_overrides(locals().copy())
|
|
@@ -174,3 +174,6 @@ class FrailtySymptom(ValueSet):
|
|
|
174
174
|
"16018431000119109", # Paresis of right lower limb (finding)
|
|
175
175
|
"16419651000119103", # Dependence on biphasic positive airway pressure ventilation due to central sleep apnea syndrome (finding)
|
|
176
176
|
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
__exports__ = ("FrailtySymptom",)
|
|
@@ -110,3 +110,12 @@ class ValueSet(CodeConstantsURLMappingMixin, metaclass=ValueSystems):
|
|
|
110
110
|
for system in cls.CODE_SYSTEM_MAPPING
|
|
111
111
|
if hasattr(cls, system)
|
|
112
112
|
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
__exports__ = (
|
|
116
|
+
"CodeConstants",
|
|
117
|
+
"CodeConstantsURLMappingMixin",
|
|
118
|
+
"CombinedValueSet",
|
|
119
|
+
"ValueSystems",
|
|
120
|
+
"ValueSet",
|
|
121
|
+
)
|
canvas_sdk/views/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__exports__ = ()
|
logger/__init__.py
CHANGED
logger/logger.py
CHANGED
plugin_runner/aws_headers.py
CHANGED
|
@@ -20,7 +20,7 @@ def aws_sig_v4_headers(
|
|
|
20
20
|
) -> dict[str, str]:
|
|
21
21
|
"""Constructs signed headers for use in requests made to AWS."""
|
|
22
22
|
algorithm = "AWS4-HMAC-SHA256"
|
|
23
|
-
now = datetime.datetime.
|
|
23
|
+
now = datetime.datetime.now(datetime.UTC)
|
|
24
24
|
amzdate = now.strftime("%Y%m%dT%H%M%SZ")
|
|
25
25
|
datestamp = now.strftime("%Y%m%d")
|
|
26
26
|
payload_hash = hashlib.sha256(payload).hexdigest()
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env uv run
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
import traceback
|
|
8
|
+
from collections import defaultdict
|
|
9
|
+
from contextlib import redirect_stderr, redirect_stdout
|
|
10
|
+
from glob import glob
|
|
11
|
+
from io import StringIO
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from textwrap import indent
|
|
14
|
+
|
|
15
|
+
import httpretty
|
|
16
|
+
|
|
17
|
+
from canvas_generated.messages.events_pb2 import PLUGIN_CREATED
|
|
18
|
+
from canvas_generated.messages.events_pb2 import Event as EventRequest
|
|
19
|
+
from canvas_sdk.events.base import Event
|
|
20
|
+
from canvas_sdk.protocols.base import BaseProtocol
|
|
21
|
+
from canvas_sdk.utils import stats
|
|
22
|
+
from plugin_runner.plugin_runner import LOADED_PLUGINS, load_or_reload_plugin
|
|
23
|
+
|
|
24
|
+
stats.STATS_ENABLED = False
|
|
25
|
+
|
|
26
|
+
ORIGINAL_PATH = sys.path.copy()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def enable_httpretty() -> None:
|
|
30
|
+
"""
|
|
31
|
+
Prevent any HTTP requests from being made.
|
|
32
|
+
"""
|
|
33
|
+
httpretty.enable(verbose=True, allow_net_connect=False)
|
|
34
|
+
|
|
35
|
+
for method in [
|
|
36
|
+
httpretty.GET,
|
|
37
|
+
httpretty.PUT,
|
|
38
|
+
httpretty.POST,
|
|
39
|
+
httpretty.DELETE,
|
|
40
|
+
httpretty.HEAD,
|
|
41
|
+
httpretty.PATCH,
|
|
42
|
+
httpretty.OPTIONS,
|
|
43
|
+
httpretty.CONNECT,
|
|
44
|
+
]:
|
|
45
|
+
httpretty.register_uri(method, re.compile(r".*"), body="{}")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def disable_httpretty() -> None:
|
|
49
|
+
"""
|
|
50
|
+
Allow normal HTTP activity.
|
|
51
|
+
"""
|
|
52
|
+
httpretty.disable()
|
|
53
|
+
httpretty.reset()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def main() -> None:
|
|
57
|
+
"""
|
|
58
|
+
Iterate through all of our plugins to verify they work with this version of the SDK.
|
|
59
|
+
"""
|
|
60
|
+
if len(sys.argv) < 2:
|
|
61
|
+
print("You must specify a base path.")
|
|
62
|
+
sys.exit(1)
|
|
63
|
+
|
|
64
|
+
base_path = sys.argv[1]
|
|
65
|
+
|
|
66
|
+
for folder in glob(f"{base_path}/**/*"):
|
|
67
|
+
path = Path(folder)
|
|
68
|
+
|
|
69
|
+
if "{{" in folder:
|
|
70
|
+
print(f"Ignoring templated path: {folder}")
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
if not path.is_dir():
|
|
74
|
+
continue
|
|
75
|
+
|
|
76
|
+
if not (path / "CANVAS_MANIFEST.json").exists():
|
|
77
|
+
print(f"Missing CANVAS_MANIFEST.json in {folder}")
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
sys.path = ORIGINAL_PATH.copy()
|
|
81
|
+
|
|
82
|
+
# this makes plugin imports work and mirrors what the plugin_runner does
|
|
83
|
+
sys.path.append((Path(".") / path.parent).as_posix())
|
|
84
|
+
|
|
85
|
+
print(path)
|
|
86
|
+
|
|
87
|
+
output = StringIO()
|
|
88
|
+
|
|
89
|
+
plugin_runner_logger = logging.getLogger("plugin_runner_logger")
|
|
90
|
+
old_handlers = plugin_runner_logger.handlers.copy()
|
|
91
|
+
plugin_runner_logger.handlers = [logging.StreamHandler(output)]
|
|
92
|
+
|
|
93
|
+
with redirect_stdout(output), redirect_stderr(output):
|
|
94
|
+
success = load_or_reload_plugin(path)
|
|
95
|
+
|
|
96
|
+
output_string = output.getvalue()
|
|
97
|
+
|
|
98
|
+
if not success:
|
|
99
|
+
print()
|
|
100
|
+
print(indent(output_string, prefix=" ").rstrip())
|
|
101
|
+
print()
|
|
102
|
+
|
|
103
|
+
plugin_runner_logger.handlers = old_handlers
|
|
104
|
+
|
|
105
|
+
enable_httpretty()
|
|
106
|
+
|
|
107
|
+
for key, plugin in LOADED_PLUGINS.items():
|
|
108
|
+
Klass: type[BaseProtocol] = plugin["class"]
|
|
109
|
+
|
|
110
|
+
if not hasattr(Klass, "compute") or not callable(Klass.compute):
|
|
111
|
+
print(f"Skipping {key} due to no compute method")
|
|
112
|
+
|
|
113
|
+
event_request = EventRequest(
|
|
114
|
+
type=PLUGIN_CREATED,
|
|
115
|
+
context=json.dumps(
|
|
116
|
+
{
|
|
117
|
+
"key": "test",
|
|
118
|
+
"fields": {
|
|
119
|
+
"coding": {"value": "test"},
|
|
120
|
+
"goal_statement": {"value": "test"},
|
|
121
|
+
"questionnaire": {"text": "test"},
|
|
122
|
+
"medication": {"extra": {"coding": "test"}},
|
|
123
|
+
"ordering_provider": {"value": "test"},
|
|
124
|
+
"text": "test",
|
|
125
|
+
},
|
|
126
|
+
"method": "GET",
|
|
127
|
+
"note_id": 5,
|
|
128
|
+
"note": {
|
|
129
|
+
"uuid": "b2bd0672-ab36-4eca-b105-884f976ae810",
|
|
130
|
+
"id": "b2bd0672-ab36-4eca-b105-884f976ae810",
|
|
131
|
+
},
|
|
132
|
+
"path": "https://test",
|
|
133
|
+
"patient_id": 5,
|
|
134
|
+
"patient": {"id": 5},
|
|
135
|
+
"results": [],
|
|
136
|
+
"search_term": "test",
|
|
137
|
+
"state": "LKD",
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
target="b2bd0672-ab36-4eca-b105-884f976ae810",
|
|
141
|
+
target_type="Patient",
|
|
142
|
+
)
|
|
143
|
+
event = Event(event_request=event_request)
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
klass = Klass(
|
|
147
|
+
event=event,
|
|
148
|
+
secrets=defaultdict(lambda: "test", {"sentinel": True}),
|
|
149
|
+
environment=defaultdict(lambda: "test", {"sentinel": True}),
|
|
150
|
+
)
|
|
151
|
+
except TypeError as e:
|
|
152
|
+
print(f"Failed to instantiate {key}:", e)
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
plugin_runner_logger = logging.getLogger("plugin_runner_logger")
|
|
156
|
+
old_handlers = plugin_runner_logger.handlers.copy()
|
|
157
|
+
plugin_runner_logger.handlers = [logging.StreamHandler(output)]
|
|
158
|
+
|
|
159
|
+
output = StringIO()
|
|
160
|
+
|
|
161
|
+
error: Exception | None = None
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
with redirect_stdout(output), redirect_stderr(output):
|
|
165
|
+
result = klass.compute()
|
|
166
|
+
except TypeError as e:
|
|
167
|
+
error = e
|
|
168
|
+
except KeyError as e:
|
|
169
|
+
error = e
|
|
170
|
+
except Exception as e:
|
|
171
|
+
error = e
|
|
172
|
+
|
|
173
|
+
plugin_runner_logger.handlers = old_handlers
|
|
174
|
+
|
|
175
|
+
result_count = len(result)
|
|
176
|
+
request_count = len(httpretty.latest_requests())
|
|
177
|
+
|
|
178
|
+
print(f"{key}: {result_count}/{request_count}")
|
|
179
|
+
|
|
180
|
+
if error:
|
|
181
|
+
print()
|
|
182
|
+
|
|
183
|
+
# abbreviate these, they come from not being able to access the database
|
|
184
|
+
if "fake_getaddrinfo" in str(error):
|
|
185
|
+
print(indent(str(error), prefix=" ").rstrip())
|
|
186
|
+
else:
|
|
187
|
+
print(indent("".join(traceback.format_exception(error)), prefix=" ").rstrip())
|
|
188
|
+
|
|
189
|
+
print()
|
|
190
|
+
|
|
191
|
+
output_string = output.getvalue()
|
|
192
|
+
|
|
193
|
+
if output_string:
|
|
194
|
+
print()
|
|
195
|
+
print(indent(output_string, prefix=" ").rstrip())
|
|
196
|
+
print()
|
|
197
|
+
|
|
198
|
+
disable_httpretty()
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
if __name__ == "__main__":
|
|
202
|
+
main()
|
plugin_runner/plugin_runner.py
CHANGED
|
@@ -33,7 +33,7 @@ from canvas_sdk.utils.stats import get_duration_ms, statsd_client
|
|
|
33
33
|
from logger import log
|
|
34
34
|
from plugin_runner.authentication import token_for_plugin
|
|
35
35
|
from plugin_runner.installation import install_plugins
|
|
36
|
-
from plugin_runner.sandbox import Sandbox
|
|
36
|
+
from plugin_runner.sandbox import Sandbox, sandbox_from_module
|
|
37
37
|
from settings import (
|
|
38
38
|
CHANNEL_NAME,
|
|
39
39
|
CUSTOMER_IDENTIFIER,
|
|
@@ -320,6 +320,12 @@ async def synchronize_plugins(run_once: bool = False) -> None:
|
|
|
320
320
|
while True:
|
|
321
321
|
message = await pubsub.get_message(ignore_subscribe_messages=True, timeout=5.0)
|
|
322
322
|
|
|
323
|
+
await pubsub.check_health()
|
|
324
|
+
|
|
325
|
+
if not pubsub.connection.is_connected: # type: ignore
|
|
326
|
+
log.info("synchronize_plugins: reconnecting to Redis")
|
|
327
|
+
await pubsub.connection.connect() # type: ignore
|
|
328
|
+
|
|
323
329
|
if message is None:
|
|
324
330
|
continue
|
|
325
331
|
|
|
@@ -350,12 +356,6 @@ async def synchronize_plugins(run_once: bool = False) -> None:
|
|
|
350
356
|
log.error(f"synchronize_plugins: load_plugins failed: {e}")
|
|
351
357
|
sentry_sdk.capture_exception(e)
|
|
352
358
|
|
|
353
|
-
await pubsub.check_health()
|
|
354
|
-
|
|
355
|
-
if not pubsub.connection.is_connected: # type: ignore
|
|
356
|
-
log.info("synchronize_plugins: reconnecting to Redis")
|
|
357
|
-
await pubsub.connection.connect() # type: ignore
|
|
358
|
-
|
|
359
359
|
if run_once:
|
|
360
360
|
break
|
|
361
361
|
|
|
@@ -437,18 +437,6 @@ def find_modules(base_path: pathlib.Path, prefix: str | None = None) -> list[str
|
|
|
437
437
|
return modules
|
|
438
438
|
|
|
439
439
|
|
|
440
|
-
def sandbox_from_module(base_path: pathlib.Path, module_name: str) -> Any:
|
|
441
|
-
"""Sandbox the code execution."""
|
|
442
|
-
module_path = base_path / str(module_name.replace(".", "/") + ".py")
|
|
443
|
-
|
|
444
|
-
if not module_path.exists():
|
|
445
|
-
raise ModuleNotFoundError(f'Could not load module "{module_name}"')
|
|
446
|
-
|
|
447
|
-
sandbox = Sandbox(module_path, namespace=module_name)
|
|
448
|
-
|
|
449
|
-
return sandbox.execute()
|
|
450
|
-
|
|
451
|
-
|
|
452
440
|
async def publish_message(message: dict) -> None:
|
|
453
441
|
"""Publish a message to the pubsub channel."""
|
|
454
442
|
log.info(f'Publishing message to pubsub channel "{CHANNEL_NAME}"')
|
|
@@ -465,7 +453,7 @@ def get_client() -> tuple[redis.Redis, redis.client.PubSub]:
|
|
|
465
453
|
return client, pubsub
|
|
466
454
|
|
|
467
455
|
|
|
468
|
-
def load_or_reload_plugin(path: pathlib.Path) ->
|
|
456
|
+
def load_or_reload_plugin(path: pathlib.Path) -> bool:
|
|
469
457
|
"""Given a path, load or reload a plugin."""
|
|
470
458
|
log.info(f'Loading plugin at "{path}"')
|
|
471
459
|
|
|
@@ -481,11 +469,11 @@ def load_or_reload_plugin(path: pathlib.Path) -> None:
|
|
|
481
469
|
log.error(f'Unable to load plugin "{name}": {e}')
|
|
482
470
|
sentry_sdk.capture_exception(e)
|
|
483
471
|
|
|
484
|
-
return
|
|
472
|
+
return False
|
|
485
473
|
|
|
486
474
|
secrets_file = path / SECRETS_FILE_NAME
|
|
487
|
-
|
|
488
475
|
secrets_json = {}
|
|
476
|
+
|
|
489
477
|
if secrets_file.exists():
|
|
490
478
|
try:
|
|
491
479
|
secrets_json = json.load(secrets_file.open())
|
|
@@ -502,7 +490,9 @@ def load_or_reload_plugin(path: pathlib.Path) -> None:
|
|
|
502
490
|
log.error(f'Unable to load plugin "{name}": {str(e)}')
|
|
503
491
|
sentry_sdk.capture_exception(e)
|
|
504
492
|
|
|
505
|
-
return
|
|
493
|
+
return False
|
|
494
|
+
|
|
495
|
+
any_failed = False
|
|
506
496
|
|
|
507
497
|
for handler in handlers:
|
|
508
498
|
# TODO add class colon validation to existing schema validation
|
|
@@ -514,10 +504,13 @@ def load_or_reload_plugin(path: pathlib.Path) -> None:
|
|
|
514
504
|
log.error(f'Unable to parse class for plugin "{name}": "{handler["class"]}"')
|
|
515
505
|
sentry_sdk.capture_exception(e)
|
|
516
506
|
|
|
507
|
+
any_failed = True
|
|
508
|
+
|
|
517
509
|
continue
|
|
518
510
|
|
|
519
511
|
try:
|
|
520
|
-
|
|
512
|
+
sandbox = sandbox_from_module(path.parent, handler_module)
|
|
513
|
+
result = sandbox.execute()
|
|
521
514
|
|
|
522
515
|
if name_and_class in LOADED_PLUGINS:
|
|
523
516
|
log.info(f"Reloading plugin '{name_and_class}'")
|
|
@@ -545,6 +538,10 @@ def load_or_reload_plugin(path: pathlib.Path) -> None:
|
|
|
545
538
|
|
|
546
539
|
sentry_sdk.capture_exception(e)
|
|
547
540
|
|
|
541
|
+
any_failed = True
|
|
542
|
+
|
|
543
|
+
return not any_failed
|
|
544
|
+
|
|
548
545
|
|
|
549
546
|
def refresh_event_type_map() -> None:
|
|
550
547
|
"""Ensure the event subscriptions are up to date."""
|