canvas 0.32.0__py3-none-any.whl → 0.33.1__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.32.0.dist-info → canvas-0.33.1.dist-info}/METADATA +2 -1
- canvas-0.33.1.dist-info/RECORD +272 -0
- canvas_generated/messages/effects_pb2.py +2 -2
- canvas_generated/messages/effects_pb2.pyi +4 -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 +6 -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 +46 -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 +81 -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 +69 -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 +20 -3
- 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 +5 -1
- 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 +26 -24
- plugin_runner/sandbox.py +497 -115
- protobufs/canvas_generated/messages/effects.proto +3 -0
- settings.py +5 -2
- canvas-0.32.0.dist-info/RECORD +0 -364
- 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.32.0.dist-info → canvas-0.33.1.dist-info}/WHEEL +0 -0
- {canvas-0.32.0.dist-info → canvas-0.33.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from base64 import b64decode
|
|
2
4
|
from secrets import compare_digest
|
|
3
5
|
from typing import TYPE_CHECKING, Any, Protocol
|
|
@@ -24,7 +26,7 @@ class Credentials:
|
|
|
24
26
|
class if they wish to just access the request directly in their authentication method.
|
|
25
27
|
"""
|
|
26
28
|
|
|
27
|
-
def __init__(self, request:
|
|
29
|
+
def __init__(self, request: Request) -> None:
|
|
28
30
|
pass
|
|
29
31
|
|
|
30
32
|
|
|
@@ -36,7 +38,7 @@ class BasicCredentials(Credentials):
|
|
|
36
38
|
them as attributes.
|
|
37
39
|
"""
|
|
38
40
|
|
|
39
|
-
def __init__(self, request:
|
|
41
|
+
def __init__(self, request: Request) -> None:
|
|
40
42
|
super().__init__(request)
|
|
41
43
|
|
|
42
44
|
authorization = request.headers.get("Authorization")
|
|
@@ -71,7 +73,7 @@ class BearerCredentials(Credentials):
|
|
|
71
73
|
Parses the token from the request Authorization header and saves it as an attribute.
|
|
72
74
|
"""
|
|
73
75
|
|
|
74
|
-
def __init__(self, request:
|
|
76
|
+
def __init__(self, request: Request) -> None:
|
|
75
77
|
super().__init__(request)
|
|
76
78
|
|
|
77
79
|
authorization = request.headers.get("Authorization")
|
|
@@ -101,7 +103,7 @@ class APIKeyCredentials(Credentials):
|
|
|
101
103
|
|
|
102
104
|
HEADER_NAME = "Authorization"
|
|
103
105
|
|
|
104
|
-
def __init__(self, request:
|
|
106
|
+
def __init__(self, request: Request) -> None:
|
|
105
107
|
super().__init__(request)
|
|
106
108
|
|
|
107
109
|
if self.HEADER_NAME not in request.headers:
|
|
@@ -132,7 +134,7 @@ class SessionCredentials(Credentials):
|
|
|
132
134
|
authenticate method.
|
|
133
135
|
"""
|
|
134
136
|
|
|
135
|
-
def __init__(self, request:
|
|
137
|
+
def __init__(self, request: Request) -> None:
|
|
136
138
|
super().__init__(request)
|
|
137
139
|
|
|
138
140
|
if (
|
|
@@ -247,3 +249,17 @@ class PatientSessionAuthMixin(AuthSchemeMixin):
|
|
|
247
249
|
if credentials.logged_in_user["type"] != "Patient":
|
|
248
250
|
raise InvalidCredentialsError
|
|
249
251
|
return True
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
__exports__ = (
|
|
255
|
+
"Credentials",
|
|
256
|
+
"BasicCredentials",
|
|
257
|
+
"BearerCredentials",
|
|
258
|
+
"APIKeyCredentials",
|
|
259
|
+
"AuthSchemeMixin",
|
|
260
|
+
"BasicAuthMixin",
|
|
261
|
+
"APIKeyAuthMixin",
|
|
262
|
+
"SessionCredentials",
|
|
263
|
+
"StaffSessionAuthMixin",
|
|
264
|
+
"PatientSessionAuthMixin",
|
|
265
|
+
)
|
|
@@ -113,3 +113,12 @@ def separate_headers(headers: Mapping[str, str]) -> list[tuple[str, str]]:
|
|
|
113
113
|
headers_list.append((key, value.strip()))
|
|
114
114
|
|
|
115
115
|
return headers_list
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
__exports__ = (
|
|
119
|
+
"KeyType",
|
|
120
|
+
"ValueType",
|
|
121
|
+
"MultiDict",
|
|
122
|
+
"CaseInsensitiveMultiDict",
|
|
123
|
+
"separate_headers",
|
|
124
|
+
)
|
canvas_sdk/protocols/__init__.py
CHANGED
canvas_sdk/protocols/base.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from typing import TYPE_CHECKING, Any, cast
|
|
2
4
|
|
|
3
5
|
import arrow
|
|
@@ -92,7 +94,7 @@ class ClinicalQualityMeasure(BaseProtocol):
|
|
|
92
94
|
incurring more SQL queries.
|
|
93
95
|
"""
|
|
94
96
|
|
|
95
|
-
def patient_id(model:
|
|
97
|
+
def patient_id(model: type[Model]) -> str:
|
|
96
98
|
if model == Patient:
|
|
97
99
|
return self.event.target.id
|
|
98
100
|
else:
|
|
@@ -130,3 +132,6 @@ class ClinicalQualityMeasure(BaseProtocol):
|
|
|
130
132
|
) from error
|
|
131
133
|
|
|
132
134
|
return self._patient_id
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
__exports__ = ("ClinicalQualityMeasure",)
|
canvas_sdk/templates/__init__.py
CHANGED
canvas_sdk/templates/utils.py
CHANGED
canvas_sdk/utils/__init__.py
CHANGED
canvas_sdk/utils/http.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import concurrent
|
|
2
2
|
import functools
|
|
3
|
+
import os
|
|
3
4
|
import time
|
|
4
5
|
import urllib.parse
|
|
5
6
|
from collections.abc import Callable, Iterable, Mapping
|
|
@@ -8,7 +9,8 @@ from functools import wraps
|
|
|
8
9
|
from typing import Any, Literal, Protocol, TypeVar, cast
|
|
9
10
|
|
|
10
11
|
import requests
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
from canvas_sdk.utils.stats import StatsDClientProxy
|
|
12
14
|
|
|
13
15
|
F = TypeVar("F", bound=Callable)
|
|
14
16
|
|
|
@@ -97,34 +99,25 @@ class Http:
|
|
|
97
99
|
|
|
98
100
|
_MAX_REQUEST_TIMEOUT_SECONDS = 30
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def __setattr__(self, name: str, value: Any) -> None:
|
|
104
|
-
"""
|
|
105
|
-
Prevent base_url or session from being updated after initialization.
|
|
106
|
-
"""
|
|
107
|
-
if name in ("base_url", "session"):
|
|
108
|
-
raise AttributeError(f"{name} is read-only")
|
|
109
|
-
|
|
110
|
-
super().__setattr__(name, value)
|
|
102
|
+
_base_url: str
|
|
103
|
+
_session: requests.Session
|
|
111
104
|
|
|
112
105
|
def join_url(self, url: str) -> str:
|
|
113
106
|
"""
|
|
114
107
|
Join a URL to the base_url.
|
|
115
108
|
"""
|
|
116
|
-
joined = urllib.parse.urljoin(self.
|
|
109
|
+
joined = urllib.parse.urljoin(self._base_url, url)
|
|
117
110
|
|
|
118
|
-
if not joined.startswith(self.
|
|
111
|
+
if not joined.startswith(self._base_url):
|
|
119
112
|
raise ValueError("You may not access other URLs using this client.")
|
|
120
113
|
|
|
121
114
|
return joined
|
|
122
115
|
|
|
123
116
|
def __init__(self, base_url: str = "") -> None:
|
|
124
|
-
|
|
125
|
-
|
|
117
|
+
self._base_url = base_url
|
|
118
|
+
self._session = requests.Session()
|
|
126
119
|
|
|
127
|
-
self.statsd_client =
|
|
120
|
+
self.statsd_client = StatsDClientProxy()
|
|
128
121
|
|
|
129
122
|
@staticmethod
|
|
130
123
|
def measure_time(fn: F) -> F:
|
|
@@ -136,7 +129,7 @@ class Http:
|
|
|
136
129
|
result = fn(self, *args, **kwargs)
|
|
137
130
|
end_time = time.time()
|
|
138
131
|
timing = int((end_time - start_time) * 1000)
|
|
139
|
-
self.statsd_client.timing(f"plugins.http_{fn.__name__}", timing)
|
|
132
|
+
self.statsd_client.timing(f"plugins.http_{fn.__name__}", timing, tags={})
|
|
140
133
|
return result
|
|
141
134
|
|
|
142
135
|
return cast(F, wrapper)
|
|
@@ -148,7 +141,7 @@ class Http:
|
|
|
148
141
|
"""Sends a GET request."""
|
|
149
142
|
if headers is None:
|
|
150
143
|
headers = {}
|
|
151
|
-
return self.
|
|
144
|
+
return self._session.get(
|
|
152
145
|
self.join_url(url),
|
|
153
146
|
headers=headers,
|
|
154
147
|
timeout=self._MAX_REQUEST_TIMEOUT_SECONDS,
|
|
@@ -163,7 +156,7 @@ class Http:
|
|
|
163
156
|
headers: Mapping[str, str | bytes | None] | None = None,
|
|
164
157
|
) -> requests.Response:
|
|
165
158
|
"""Sends a POST request."""
|
|
166
|
-
return self.
|
|
159
|
+
return self._session.post(
|
|
167
160
|
self.join_url(url),
|
|
168
161
|
json=json,
|
|
169
162
|
data=data,
|
|
@@ -180,7 +173,7 @@ class Http:
|
|
|
180
173
|
headers: Mapping[str, str | bytes | None] | None = None,
|
|
181
174
|
) -> requests.Response:
|
|
182
175
|
"""Sends a PUT request."""
|
|
183
|
-
return self.
|
|
176
|
+
return self._session.put(
|
|
184
177
|
self.join_url(url),
|
|
185
178
|
json=json,
|
|
186
179
|
data=data,
|
|
@@ -197,7 +190,7 @@ class Http:
|
|
|
197
190
|
headers: Mapping[str, str | bytes | None] | None = None,
|
|
198
191
|
) -> requests.Response:
|
|
199
192
|
"""Sends a PATCH request."""
|
|
200
|
-
return self.
|
|
193
|
+
return self._session.patch(
|
|
201
194
|
self.join_url(url),
|
|
202
195
|
json=json,
|
|
203
196
|
data=data,
|
|
@@ -233,7 +226,50 @@ class Http:
|
|
|
233
226
|
return [future.result() for future in futures]
|
|
234
227
|
|
|
235
228
|
|
|
236
|
-
class
|
|
229
|
+
class JsonOnlyHttp(Http):
|
|
230
|
+
def get(
|
|
231
|
+
self,
|
|
232
|
+
url: str,
|
|
233
|
+
headers: Mapping[str, str | bytes | None] | None = None,
|
|
234
|
+
) -> requests.Response:
|
|
235
|
+
raise NotImplementedError
|
|
236
|
+
|
|
237
|
+
def get_json(
|
|
238
|
+
self,
|
|
239
|
+
url: str,
|
|
240
|
+
headers: Mapping[str, str | bytes | None] | None = None,
|
|
241
|
+
) -> dict[str, Any]:
|
|
242
|
+
return super().get(url, headers).json()
|
|
243
|
+
|
|
244
|
+
def post(
|
|
245
|
+
self,
|
|
246
|
+
url: str,
|
|
247
|
+
json: dict | None = None,
|
|
248
|
+
data: dict | str | list | bytes | None = None,
|
|
249
|
+
headers: Mapping[str, str | bytes | None] | None = None,
|
|
250
|
+
) -> requests.Response:
|
|
251
|
+
raise NotImplementedError
|
|
252
|
+
|
|
253
|
+
def put(
|
|
254
|
+
self,
|
|
255
|
+
url: str,
|
|
256
|
+
json: dict | None = None,
|
|
257
|
+
data: dict | str | list | bytes | None = None,
|
|
258
|
+
headers: Mapping[str, str | bytes | None] | None = None,
|
|
259
|
+
) -> requests.Response:
|
|
260
|
+
raise NotImplementedError
|
|
261
|
+
|
|
262
|
+
def patch(
|
|
263
|
+
self,
|
|
264
|
+
url: str,
|
|
265
|
+
json: dict | None = None,
|
|
266
|
+
data: dict | str | list | bytes | None = None,
|
|
267
|
+
headers: Mapping[str, str | bytes | None] | None = None,
|
|
268
|
+
) -> requests.Response:
|
|
269
|
+
raise NotImplementedError
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class OntologiesHttp(JsonOnlyHttp):
|
|
237
273
|
"""
|
|
238
274
|
An HTTP client for the ontologies service.
|
|
239
275
|
"""
|
|
@@ -241,13 +277,10 @@ class OntologiesHttp(Http):
|
|
|
241
277
|
def __init__(self) -> None:
|
|
242
278
|
super().__init__(base_url="https://ontologies.canvasmedical.com")
|
|
243
279
|
|
|
244
|
-
|
|
245
|
-
import os
|
|
246
|
-
|
|
247
|
-
self.session.headers.update({"Authorization": os.getenv("PRE_SHARED_KEY", "")})
|
|
280
|
+
self._session.headers.update({"Authorization": os.getenv("PRE_SHARED_KEY", "")})
|
|
248
281
|
|
|
249
282
|
|
|
250
|
-
class ScienceHttp(
|
|
283
|
+
class ScienceHttp(JsonOnlyHttp):
|
|
251
284
|
"""
|
|
252
285
|
An HTTP client for the ontologies service.
|
|
253
286
|
"""
|
|
@@ -255,18 +288,19 @@ class ScienceHttp(Http):
|
|
|
255
288
|
def __init__(self) -> None:
|
|
256
289
|
super().__init__(base_url="https://science.canvasmedical.com")
|
|
257
290
|
|
|
258
|
-
|
|
259
|
-
import os
|
|
291
|
+
self._session.headers.update({"Authorization": os.getenv("PRE_SHARED_KEY", "")})
|
|
260
292
|
|
|
261
|
-
self.session.headers.update({"Authorization": os.getenv("PRE_SHARED_KEY", "")})
|
|
262
293
|
|
|
294
|
+
ontologies_http = OntologiesHttp()
|
|
295
|
+
science_http = ScienceHttp()
|
|
263
296
|
|
|
264
|
-
__all__ =
|
|
297
|
+
__all__ = __exports__ = (
|
|
298
|
+
"ThreadPoolExecutor",
|
|
265
299
|
"Http",
|
|
266
|
-
"
|
|
267
|
-
"
|
|
300
|
+
"ontologies_http",
|
|
301
|
+
"science_http",
|
|
268
302
|
"batch_get",
|
|
269
303
|
"batch_post",
|
|
270
304
|
"batch_put",
|
|
271
305
|
"batch_patch",
|
|
272
|
-
|
|
306
|
+
)
|
canvas_sdk/utils/plugins.py
CHANGED
|
@@ -18,8 +18,12 @@ def plugin_only(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
|
18
18
|
|
|
19
19
|
plugin_name = caller.f_globals["__name__"].split(".")[0]
|
|
20
20
|
plugin_dir = Path(PLUGIN_DIRECTORY) / plugin_name
|
|
21
|
+
kwargs["plugin_name"] = plugin_name
|
|
21
22
|
kwargs["plugin_dir"] = plugin_dir.resolve()
|
|
22
23
|
|
|
23
24
|
return func(*args, **kwargs)
|
|
24
25
|
|
|
25
26
|
return wrapper
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__exports__ = ()
|
canvas_sdk/utils/stats.py
CHANGED
|
@@ -31,6 +31,9 @@ def tags_to_line_protocol(tags: dict[str, Any]) -> str:
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
STATS_ENABLED = True
|
|
35
|
+
|
|
36
|
+
|
|
34
37
|
class StatsDClientProxy:
|
|
35
38
|
"""Proxy for a StatsD client."""
|
|
36
39
|
|
|
@@ -45,6 +48,9 @@ class StatsDClientProxy:
|
|
|
45
48
|
value (float): The value to report.
|
|
46
49
|
tags (dict[str, str]): Dictionary of tags to attach to the metric.
|
|
47
50
|
"""
|
|
51
|
+
if not STATS_ENABLED:
|
|
52
|
+
return
|
|
53
|
+
|
|
48
54
|
statsd_tags = tags_to_line_protocol(tags)
|
|
49
55
|
self.client.gauge(f"{metric_name},{statsd_tags}", value)
|
|
50
56
|
|
|
@@ -56,8 +62,13 @@ class StatsDClientProxy:
|
|
|
56
62
|
delta (float | timedelta): The value to report.
|
|
57
63
|
tags (dict[str, str]): Dictionary of tags to attach to the metric.
|
|
58
64
|
"""
|
|
65
|
+
if not STATS_ENABLED:
|
|
66
|
+
return
|
|
67
|
+
|
|
59
68
|
statsd_tags = tags_to_line_protocol(tags)
|
|
60
69
|
self.client.timing(f"{metric_name},{statsd_tags}", delta)
|
|
61
70
|
|
|
62
71
|
|
|
63
72
|
statsd_client = StatsDClientProxy()
|
|
73
|
+
|
|
74
|
+
__exports__ = ()
|
canvas_sdk/v1/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__exports__ = ()
|
canvas_sdk/v1/apps.py
CHANGED
canvas_sdk/v1/data/__init__.py
CHANGED
|
@@ -54,7 +54,7 @@ from .staff import Staff, StaffContactPoint
|
|
|
54
54
|
from .task import Task, TaskComment, TaskLabel, TaskTaskLabel
|
|
55
55
|
from .user import CanvasUser
|
|
56
56
|
|
|
57
|
-
__all__ =
|
|
57
|
+
__all__ = __exports__ = (
|
|
58
58
|
"Appointment",
|
|
59
59
|
"AppointmentExternalIdentifier",
|
|
60
60
|
"AllergyIntolerance",
|
|
@@ -120,4 +120,4 @@ __all__ = [
|
|
|
120
120
|
"Transactor",
|
|
121
121
|
"TransactorAddress",
|
|
122
122
|
"TransactorPhone",
|
|
123
|
-
|
|
123
|
+
)
|
|
@@ -76,3 +76,10 @@ class AppointmentExternalIdentifier(models.Model):
|
|
|
76
76
|
appointment = models.ForeignKey(
|
|
77
77
|
Appointment, on_delete=models.DO_NOTHING, related_name="external_identifiers"
|
|
78
78
|
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
__exports__ = (
|
|
82
|
+
"AppointmentProgressStatus",
|
|
83
|
+
"Appointment",
|
|
84
|
+
"AppointmentExternalIdentifier",
|
|
85
|
+
)
|
canvas_sdk/v1/data/assessment.py
CHANGED
canvas_sdk/v1/data/base.py
CHANGED
canvas_sdk/v1/data/billing.py
CHANGED
canvas_sdk/v1/data/care_team.py
CHANGED
canvas_sdk/v1/data/command.py
CHANGED
canvas_sdk/v1/data/common.py
CHANGED
|
@@ -154,3 +154,21 @@ class AddressState(models.TextChoices):
|
|
|
154
154
|
|
|
155
155
|
ACTIVE = "active", "Active"
|
|
156
156
|
DELETED = "deleted", "Deleted"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
__exports__ = (
|
|
160
|
+
"DocumentReviewMode",
|
|
161
|
+
"OrderStatus",
|
|
162
|
+
"ReviewPatientCommunicationMethod",
|
|
163
|
+
"ReviewStatus",
|
|
164
|
+
"PersonSex",
|
|
165
|
+
"TaxIDType",
|
|
166
|
+
"ColorEnum",
|
|
167
|
+
"Origin",
|
|
168
|
+
"ContactPointSystem",
|
|
169
|
+
"ContactPointUse",
|
|
170
|
+
"ContactPointState",
|
|
171
|
+
"AddressUse",
|
|
172
|
+
"AddressType",
|
|
173
|
+
"AddressState",
|
|
174
|
+
)
|
canvas_sdk/v1/data/condition.py
CHANGED
canvas_sdk/v1/data/coverage.py
CHANGED
|
@@ -292,3 +292,17 @@ class TransactorPhone(models.Model):
|
|
|
292
292
|
|
|
293
293
|
def __str__(self) -> str:
|
|
294
294
|
return f"id={self.id}"
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
__exports__ = (
|
|
298
|
+
"CoverageStack",
|
|
299
|
+
"CoverageState",
|
|
300
|
+
"CoverageType",
|
|
301
|
+
"CoverageRelationshipCode",
|
|
302
|
+
"TransactorCoverageType",
|
|
303
|
+
"TransactorType",
|
|
304
|
+
"Coverage",
|
|
305
|
+
"Transactor",
|
|
306
|
+
"TransactorAddress",
|
|
307
|
+
"TransactorPhone",
|
|
308
|
+
)
|
canvas_sdk/v1/data/device.py
CHANGED
canvas_sdk/v1/data/imaging.py
CHANGED
|
@@ -97,3 +97,10 @@ class ImagingReport(models.Model):
|
|
|
97
97
|
result_date = models.DateField()
|
|
98
98
|
original_date = models.DateField()
|
|
99
99
|
review = models.ForeignKey(ImagingReview, on_delete=models.DO_NOTHING, null=True)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
__exports__ = (
|
|
103
|
+
"ImagingOrder",
|
|
104
|
+
"ImagingReview",
|
|
105
|
+
"ImagingReport",
|
|
106
|
+
)
|
canvas_sdk/v1/data/lab.py
CHANGED
|
@@ -349,3 +349,19 @@ class LabPartnerTest(models.Model):
|
|
|
349
349
|
order_name = models.TextField()
|
|
350
350
|
keywords = models.TextField(blank=True)
|
|
351
351
|
cpt_code = models.CharField(max_length=256, blank=True, null=True)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
__exports__ = (
|
|
355
|
+
"TransmissionType",
|
|
356
|
+
"LabReport",
|
|
357
|
+
"LabReviewQuerySet",
|
|
358
|
+
"LabReview",
|
|
359
|
+
"LabValue",
|
|
360
|
+
"LabValueCoding",
|
|
361
|
+
"LabOrder",
|
|
362
|
+
"LabOrderReason",
|
|
363
|
+
"LabOrderReasonCondition",
|
|
364
|
+
"LabTest",
|
|
365
|
+
"LabPartner",
|
|
366
|
+
"LabPartnerTest",
|
|
367
|
+
)
|
canvas_sdk/v1/data/medication.py
CHANGED
canvas_sdk/v1/data/note.py
CHANGED
|
@@ -160,3 +160,12 @@ class Note(models.Model):
|
|
|
160
160
|
location = models.ForeignKey("v1.PracticeLocation", on_delete=models.DO_NOTHING, null=True)
|
|
161
161
|
datetime_of_service = models.DateTimeField()
|
|
162
162
|
place_of_service = models.CharField()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
__exports__ = (
|
|
166
|
+
"NoteTypeCategories",
|
|
167
|
+
"PracticeLocationPOS",
|
|
168
|
+
"NoteTypes",
|
|
169
|
+
"NoteType",
|
|
170
|
+
"Note",
|
|
171
|
+
)
|
|
@@ -122,3 +122,12 @@ class ObservationValueCoding(models.Model):
|
|
|
122
122
|
observation = models.ForeignKey(
|
|
123
123
|
Observation, on_delete=models.DO_NOTHING, related_name="value_codings", null=True
|
|
124
124
|
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
__exports__ = (
|
|
128
|
+
"Observation",
|
|
129
|
+
"ObservationCoding",
|
|
130
|
+
"ObservationComponent",
|
|
131
|
+
"ObservationComponentCoding",
|
|
132
|
+
"ObservationValueCoding",
|
|
133
|
+
)
|