canvas 0.33.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.33.0.dist-info → canvas-0.33.1.dist-info}/METADATA +2 -1
- canvas-0.33.1.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 +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 +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.33.1.dist-info}/WHEEL +0 -0
- {canvas-0.33.0.dist-info → canvas-0.33.1.dist-info}/entry_points.txt +0 -0
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
|
+
)
|
canvas_sdk/v1/data/patient.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from typing import TYPE_CHECKING, Any
|
|
2
4
|
|
|
3
5
|
import arrow
|
|
@@ -82,10 +84,10 @@ class Patient(models.Model):
|
|
|
82
84
|
default_provider_id = models.BigIntegerField()
|
|
83
85
|
user = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
|
|
84
86
|
|
|
85
|
-
settings:
|
|
87
|
+
settings: RelatedManager[PatientSetting]
|
|
86
88
|
|
|
87
89
|
@classmethod
|
|
88
|
-
def find(cls, id: str) ->
|
|
90
|
+
def find(cls, id: str) -> Patient:
|
|
89
91
|
"""Find a patient by id."""
|
|
90
92
|
return cls._default_manager.get(id=id)
|
|
91
93
|
|
|
@@ -223,3 +225,17 @@ class PatientSetting(models.Model):
|
|
|
223
225
|
)
|
|
224
226
|
name = models.CharField()
|
|
225
227
|
value = models.JSONField()
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
__exports__ = (
|
|
231
|
+
"SexAtBirth",
|
|
232
|
+
"PatientSettingConstants",
|
|
233
|
+
"Patient",
|
|
234
|
+
"PatientContactPoint",
|
|
235
|
+
"PatientAddress",
|
|
236
|
+
"PatientExternalIdentifier",
|
|
237
|
+
"PatientSetting",
|
|
238
|
+
# not defined here but used by current plugins
|
|
239
|
+
"ContactPointState",
|
|
240
|
+
"ContactPointSystem",
|
|
241
|
+
)
|
|
@@ -67,3 +67,10 @@ class ProtocolOverride(models.Model):
|
|
|
67
67
|
cycle_quantity = models.IntegerField()
|
|
68
68
|
cycle_unit = models.CharField(choices=IntervalUnit.choices)
|
|
69
69
|
status = models.CharField(choices=Status.choices)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
__exports__ = (
|
|
73
|
+
"IntervalUnit",
|
|
74
|
+
"Status",
|
|
75
|
+
"ProtocolOverride",
|
|
76
|
+
)
|
|
@@ -107,7 +107,7 @@ class Questionnaire(models.Model):
|
|
|
107
107
|
code_system = models.CharField()
|
|
108
108
|
code = models.CharField()
|
|
109
109
|
search_tags = models.CharField()
|
|
110
|
-
questions = models.ManyToManyField(Question, through="v1.QuestionnaireQuestionMap")
|
|
110
|
+
questions = models.ManyToManyField(Question, through="v1.QuestionnaireQuestionMap")
|
|
111
111
|
use_in_shx = models.BooleanField()
|
|
112
112
|
carry_forward = models.TextField()
|
|
113
113
|
|
|
@@ -159,9 +159,9 @@ class Interview(models.Model):
|
|
|
159
159
|
)
|
|
160
160
|
note_id = models.BigIntegerField()
|
|
161
161
|
appointment_id = models.BigIntegerField()
|
|
162
|
-
questionnaires = models.ManyToManyField(
|
|
162
|
+
questionnaires = models.ManyToManyField(
|
|
163
163
|
Questionnaire,
|
|
164
|
-
through="v1.InterviewQuestionnaireMap",
|
|
164
|
+
through="v1.InterviewQuestionnaireMap",
|
|
165
165
|
)
|
|
166
166
|
progress_status = models.CharField()
|
|
167
167
|
created = models.DateTimeField()
|
|
@@ -210,3 +210,16 @@ class InterviewQuestionResponse(models.Model):
|
|
|
210
210
|
questionnaire_state = models.TextField()
|
|
211
211
|
interview_state = models.TextField()
|
|
212
212
|
comment = models.CharField()
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
__exports__ = (
|
|
216
|
+
"ResponseOptionSet",
|
|
217
|
+
"ResponseOption",
|
|
218
|
+
"Question",
|
|
219
|
+
"Questionnaire",
|
|
220
|
+
"QuestionnaireQuestionMap",
|
|
221
|
+
"InterviewQuerySet",
|
|
222
|
+
"Interview",
|
|
223
|
+
"InterviewQuestionnaireMap",
|
|
224
|
+
"InterviewQuestionResponse",
|
|
225
|
+
)
|
canvas_sdk/v1/data/staff.py
CHANGED
|
@@ -84,3 +84,6 @@ class StaffContactPoint(models.Model):
|
|
|
84
84
|
rank = models.IntegerField()
|
|
85
85
|
state = models.CharField(choices=ContactPointState.choices)
|
|
86
86
|
staff = models.ForeignKey(Staff, on_delete=models.DO_NOTHING, related_name="telecom")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
__exports__ = ("Staff", "StaffContactPoint")
|
canvas_sdk/v1/data/task.py
CHANGED
|
@@ -108,3 +108,15 @@ class TaskTaskLabel(models.Model):
|
|
|
108
108
|
dbid = models.BigIntegerField(primary_key=True)
|
|
109
109
|
task_label = models.ForeignKey(TaskLabel, on_delete=models.DO_NOTHING, null=True)
|
|
110
110
|
task = models.ForeignKey(Task, on_delete=models.DO_NOTHING, null=True)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
__exports__ = (
|
|
114
|
+
"TaskType",
|
|
115
|
+
"EventType",
|
|
116
|
+
"TaskStatus",
|
|
117
|
+
"TaskLabelModule",
|
|
118
|
+
"Task",
|
|
119
|
+
"TaskComment",
|
|
120
|
+
"TaskLabel",
|
|
121
|
+
"TaskTaskLabel",
|
|
122
|
+
)
|
canvas_sdk/v1/data/team.py
CHANGED
|
@@ -52,7 +52,7 @@ class Team(models.Model):
|
|
|
52
52
|
name = models.CharField()
|
|
53
53
|
responsibilities = ArrayField(models.CharField(choices=TeamResponsibility.choices))
|
|
54
54
|
members = models.ManyToManyField( # type: ignore[var-annotated]
|
|
55
|
-
"v1.Staff",
|
|
55
|
+
"v1.Staff",
|
|
56
56
|
related_name="teams",
|
|
57
57
|
db_table="canvas_sdk_data_api_team_members_001",
|
|
58
58
|
)
|
|
@@ -74,3 +74,10 @@ class TeamContactPoint(models.Model):
|
|
|
74
74
|
rank = models.IntegerField()
|
|
75
75
|
state = models.CharField(choices=ContactPointState.choices)
|
|
76
76
|
team = models.ForeignKey(Team, on_delete=models.DO_NOTHING, related_name="telecom")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
__exports__ = (
|
|
80
|
+
"TeamResponsibility",
|
|
81
|
+
"Team",
|
|
82
|
+
"TeamContactPoint",
|
|
83
|
+
)
|
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__ = ()
|