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.

Files changed (254) hide show
  1. {canvas-0.33.0.dist-info → canvas-0.33.1.dist-info}/METADATA +2 -1
  2. canvas-0.33.1.dist-info/RECORD +272 -0
  3. canvas_sdk/__init__.py +3 -0
  4. canvas_sdk/commands/__init__.py +1 -1
  5. canvas_sdk/commands/base.py +3 -0
  6. canvas_sdk/commands/commands/__init__.py +1 -0
  7. canvas_sdk/commands/commands/adjust_prescription.py +3 -0
  8. canvas_sdk/commands/commands/allergy.py +7 -0
  9. canvas_sdk/commands/commands/assess.py +2 -0
  10. canvas_sdk/commands/commands/close_goal.py +3 -0
  11. canvas_sdk/commands/commands/diagnose.py +3 -0
  12. canvas_sdk/commands/commands/exam.py +3 -0
  13. canvas_sdk/commands/commands/family_history.py +3 -0
  14. canvas_sdk/commands/commands/follow_up.py +3 -0
  15. canvas_sdk/commands/commands/goal.py +3 -0
  16. canvas_sdk/commands/commands/history_present_illness.py +3 -0
  17. canvas_sdk/commands/commands/imaging_order.py +3 -0
  18. canvas_sdk/commands/commands/instruct.py +3 -0
  19. canvas_sdk/commands/commands/lab_order.py +3 -0
  20. canvas_sdk/commands/commands/medical_history.py +3 -0
  21. canvas_sdk/commands/commands/medication_statement.py +2 -0
  22. canvas_sdk/commands/commands/past_surgical_history.py +3 -0
  23. canvas_sdk/commands/commands/perform.py +3 -0
  24. canvas_sdk/commands/commands/plan.py +3 -0
  25. canvas_sdk/commands/commands/prescribe.py +8 -0
  26. canvas_sdk/commands/commands/questionnaire/__init__.py +3 -13
  27. canvas_sdk/commands/commands/questionnaire/question.py +10 -0
  28. canvas_sdk/commands/commands/reason_for_visit.py +3 -0
  29. canvas_sdk/commands/commands/refer.py +3 -0
  30. canvas_sdk/commands/commands/refill.py +3 -0
  31. canvas_sdk/commands/commands/remove_allergy.py +3 -0
  32. canvas_sdk/commands/commands/resolve_condition.py +3 -0
  33. canvas_sdk/commands/commands/review_of_systems.py +3 -0
  34. canvas_sdk/commands/commands/stop_medication.py +3 -0
  35. canvas_sdk/commands/commands/structured_assessment.py +3 -0
  36. canvas_sdk/commands/commands/task.py +7 -0
  37. canvas_sdk/commands/commands/update_diagnosis.py +3 -0
  38. canvas_sdk/commands/commands/update_goal.py +3 -0
  39. canvas_sdk/commands/commands/vitals.py +3 -0
  40. canvas_sdk/commands/constants.py +8 -0
  41. canvas_sdk/effects/__init__.py +1 -1
  42. canvas_sdk/effects/banner_alert/__init__.py +1 -1
  43. canvas_sdk/effects/banner_alert/add_banner_alert.py +3 -0
  44. canvas_sdk/effects/banner_alert/remove_banner_alert.py +3 -0
  45. canvas_sdk/effects/base.py +7 -0
  46. canvas_sdk/effects/billing_line_item/__init__.py +5 -1
  47. canvas_sdk/effects/billing_line_item/add_billing_line_item.py +3 -0
  48. canvas_sdk/effects/billing_line_item/remove_billing_line_item.py +3 -0
  49. canvas_sdk/effects/billing_line_item/update_billing_line_item.py +3 -0
  50. canvas_sdk/effects/launch_modal.py +3 -0
  51. canvas_sdk/effects/patient_chart_summary_configuration.py +3 -0
  52. canvas_sdk/effects/patient_portal/__init__.py +1 -0
  53. canvas_sdk/effects/patient_portal/application_configuration.py +3 -0
  54. canvas_sdk/effects/patient_portal/form_result.py +3 -0
  55. canvas_sdk/effects/patient_portal_menu_configuration.py +3 -0
  56. canvas_sdk/effects/patient_profile_configuration.py +5 -1
  57. canvas_sdk/effects/protocol_card/__init__.py +1 -1
  58. canvas_sdk/effects/protocol_card/protocol_card.py +6 -0
  59. canvas_sdk/effects/questionnaire_result.py +3 -0
  60. canvas_sdk/effects/send_invite.py +3 -0
  61. canvas_sdk/effects/show_button.py +3 -0
  62. canvas_sdk/effects/simple_api.py +9 -0
  63. canvas_sdk/effects/surescripts/__init__.py +2 -2
  64. canvas_sdk/effects/surescripts/surescripts_messages.py +7 -0
  65. canvas_sdk/effects/task/__init__.py +6 -1
  66. canvas_sdk/effects/task/task.py +8 -0
  67. canvas_sdk/effects/update_user.py +3 -0
  68. canvas_sdk/effects/widgets/__init__.py +1 -1
  69. canvas_sdk/effects/widgets/portal_widget.py +3 -0
  70. canvas_sdk/events/__init__.py +6 -1
  71. canvas_sdk/events/base.py +3 -0
  72. canvas_sdk/handlers/__init__.py +1 -1
  73. canvas_sdk/handlers/action_button.py +6 -0
  74. canvas_sdk/handlers/application.py +3 -0
  75. canvas_sdk/handlers/base.py +3 -0
  76. canvas_sdk/handlers/cron_task.py +3 -0
  77. canvas_sdk/handlers/simple_api/__init__.py +3 -2
  78. canvas_sdk/handlers/simple_api/api.py +26 -1
  79. canvas_sdk/handlers/simple_api/exceptions.py +10 -0
  80. canvas_sdk/handlers/simple_api/security.py +21 -5
  81. canvas_sdk/handlers/simple_api/tools.py +9 -0
  82. canvas_sdk/protocols/__init__.py +1 -1
  83. canvas_sdk/protocols/base.py +3 -0
  84. canvas_sdk/protocols/clinical_quality_measure.py +6 -1
  85. canvas_sdk/protocols/timeframe.py +3 -0
  86. canvas_sdk/questionnaires/__init__.py +1 -1
  87. canvas_sdk/questionnaires/utils.py +7 -0
  88. canvas_sdk/templates/__init__.py +1 -1
  89. canvas_sdk/templates/utils.py +3 -0
  90. canvas_sdk/utils/__init__.py +1 -1
  91. canvas_sdk/utils/http.py +69 -35
  92. canvas_sdk/utils/plugins.py +4 -0
  93. canvas_sdk/utils/stats.py +11 -0
  94. canvas_sdk/v1/__init__.py +1 -0
  95. canvas_sdk/v1/apps.py +3 -0
  96. canvas_sdk/v1/data/__init__.py +2 -2
  97. canvas_sdk/v1/data/allergy_intolerance.py +3 -0
  98. canvas_sdk/v1/data/appointment.py +7 -0
  99. canvas_sdk/v1/data/assessment.py +3 -0
  100. canvas_sdk/v1/data/banner_alert.py +3 -0
  101. canvas_sdk/v1/data/base.py +3 -0
  102. canvas_sdk/v1/data/billing.py +7 -0
  103. canvas_sdk/v1/data/care_team.py +7 -0
  104. canvas_sdk/v1/data/command.py +3 -0
  105. canvas_sdk/v1/data/common.py +18 -0
  106. canvas_sdk/v1/data/condition.py +7 -0
  107. canvas_sdk/v1/data/coverage.py +14 -0
  108. canvas_sdk/v1/data/detected_issue.py +3 -0
  109. canvas_sdk/v1/data/device.py +3 -0
  110. canvas_sdk/v1/data/imaging.py +7 -0
  111. canvas_sdk/v1/data/lab.py +16 -0
  112. canvas_sdk/v1/data/medication.py +3 -0
  113. canvas_sdk/v1/data/note.py +9 -0
  114. canvas_sdk/v1/data/observation.py +9 -0
  115. canvas_sdk/v1/data/organization.py +3 -0
  116. canvas_sdk/v1/data/patient.py +18 -2
  117. canvas_sdk/v1/data/practicelocation.py +7 -0
  118. canvas_sdk/v1/data/protocol_override.py +7 -0
  119. canvas_sdk/v1/data/questionnaire.py +16 -3
  120. canvas_sdk/v1/data/reason_for_visit.py +3 -0
  121. canvas_sdk/v1/data/staff.py +3 -0
  122. canvas_sdk/v1/data/task.py +12 -0
  123. canvas_sdk/v1/data/team.py +8 -1
  124. canvas_sdk/v1/data/user.py +3 -0
  125. canvas_sdk/v1/models.py +2 -0
  126. canvas_sdk/value_set/__init__.py +1 -0
  127. canvas_sdk/value_set/_utilities.py +16 -0
  128. canvas_sdk/value_set/custom.py +4 -0
  129. canvas_sdk/value_set/hcc2018.py +3 -0
  130. canvas_sdk/value_set/v2022/__init__.py +1 -0
  131. canvas_sdk/value_set/v2022/adverse_event.py +3 -0
  132. canvas_sdk/value_set/v2022/allergy.py +5 -0
  133. canvas_sdk/value_set/v2022/assessment.py +5 -0
  134. canvas_sdk/value_set/v2022/communication.py +5 -0
  135. canvas_sdk/value_set/v2022/condition.py +5 -0
  136. canvas_sdk/value_set/v2022/device.py +5 -0
  137. canvas_sdk/value_set/v2022/diagnostic_study.py +5 -0
  138. canvas_sdk/value_set/v2022/encounter.py +5 -0
  139. canvas_sdk/value_set/v2022/immunization.py +5 -0
  140. canvas_sdk/value_set/v2022/individual_characteristic.py +5 -0
  141. canvas_sdk/value_set/v2022/intervention.py +5 -0
  142. canvas_sdk/value_set/v2022/laboratory_test.py +5 -0
  143. canvas_sdk/value_set/v2022/medication.py +5 -0
  144. canvas_sdk/value_set/v2022/physical_exam.py +5 -0
  145. canvas_sdk/value_set/v2022/procedure.py +5 -0
  146. canvas_sdk/value_set/v2022/symptom.py +3 -0
  147. canvas_sdk/value_set/value_set.py +9 -0
  148. canvas_sdk/views/__init__.py +1 -0
  149. logger/__init__.py +2 -0
  150. logger/logger.py +3 -0
  151. plugin_runner/aws_headers.py +1 -1
  152. plugin_runner/load_all_plugins.py +202 -0
  153. plugin_runner/plugin_runner.py +21 -24
  154. plugin_runner/sandbox.py +497 -115
  155. settings.py +5 -2
  156. canvas-0.33.0.dist-info/RECORD +0 -366
  157. canvas_cli/apps/auth/tests.py +0 -155
  158. canvas_cli/apps/plugin/tests.py +0 -85
  159. canvas_cli/conftest.py +0 -28
  160. canvas_cli/tests.py +0 -217
  161. canvas_cli/utils/context/tests.py +0 -131
  162. canvas_cli/utils/print/tests.py +0 -69
  163. canvas_cli/utils/urls/tests.py +0 -12
  164. canvas_cli/utils/validators/tests.py +0 -37
  165. canvas_sdk/commands/tests/protocol/__init__.py +0 -0
  166. canvas_sdk/commands/tests/protocol/tests.py +0 -83
  167. canvas_sdk/commands/tests/schema/__init__.py +0 -0
  168. canvas_sdk/commands/tests/schema/tests.py +0 -108
  169. canvas_sdk/commands/tests/test_base_command.py +0 -81
  170. canvas_sdk/commands/tests/test_utils.py +0 -375
  171. canvas_sdk/commands/tests/unit/__init__.py +0 -0
  172. canvas_sdk/commands/tests/unit/tests.py +0 -278
  173. canvas_sdk/effects/banner_alert/tests.py +0 -288
  174. canvas_sdk/effects/protocol_card/tests.py +0 -191
  175. canvas_sdk/questionnaires/tests/__init__.py +0 -0
  176. canvas_sdk/questionnaires/tests/test_utils.py +0 -74
  177. canvas_sdk/templates/tests/__init__.py +0 -0
  178. canvas_sdk/templates/tests/test_utils.py +0 -43
  179. canvas_sdk/tests/__init__.py +0 -0
  180. canvas_sdk/tests/handlers/__init__.py +0 -0
  181. canvas_sdk/tests/handlers/test_simple_api.py +0 -1167
  182. canvas_sdk/utils/tests.py +0 -72
  183. canvas_sdk/value_set/tests/test_value_sets.py +0 -72
  184. plugin_runner/tests/__init__.py +0 -0
  185. plugin_runner/tests/fixtures/plugins/example_plugin/CANVAS_MANIFEST.json +0 -29
  186. plugin_runner/tests/fixtures/plugins/example_plugin/README.md +0 -12
  187. plugin_runner/tests/fixtures/plugins/example_plugin/__init__.py +0 -0
  188. plugin_runner/tests/fixtures/plugins/example_plugin/protocols/__init__.py +0 -0
  189. plugin_runner/tests/fixtures/plugins/example_plugin/protocols/my_protocol.py +0 -18
  190. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/CANVAS_MANIFEST.json +0 -38
  191. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/README.md +0 -11
  192. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/__init__.py +0 -0
  193. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/protocols/my_protocol.py +0 -33
  194. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/__init__.py +0 -3
  195. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/templates/base.py +0 -6
  196. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/__init__.py +0 -5
  197. plugin_runner/tests/fixtures/plugins/test_implicit_imports_plugin/utils/base.py +0 -4
  198. plugin_runner/tests/fixtures/plugins/test_load_questionnaire/CANVAS_MANIFEST.json +0 -52
  199. plugin_runner/tests/fixtures/plugins/test_load_questionnaire/README.md +0 -11
  200. plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/__init__.py +0 -0
  201. plugin_runner/tests/fixtures/plugins/test_load_questionnaire/protocols/my_protocol.py +0 -39
  202. plugin_runner/tests/fixtures/plugins/test_load_questionnaire/questionnaires/example_questionnaire.yml +0 -61
  203. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/CANVAS_MANIFEST.json +0 -29
  204. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/README.md +0 -12
  205. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/__init__.py +0 -0
  206. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/other_module/base.py +0 -10
  207. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/__init__.py +0 -0
  208. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_plugin/protocols/my_protocol.py +0 -18
  209. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/CANVAS_MANIFEST.json +0 -29
  210. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/README.md +0 -12
  211. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/__init__.py +0 -0
  212. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/other_module/base.py +0 -10
  213. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/__init__.py +0 -0
  214. plugin_runner/tests/fixtures/plugins/test_module_forbidden_imports_runtime_plugin/protocols/my_protocol.py +0 -18
  215. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/CANVAS_MANIFEST.json +0 -29
  216. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/README.md +0 -12
  217. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/__init__.py +0 -0
  218. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/base.py +0 -3
  219. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/__init__.py +0 -0
  220. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/my_protocol.py +0 -18
  221. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/CANVAS_MANIFEST.json +0 -29
  222. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/README.md +0 -12
  223. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/__init__.py +0 -0
  224. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/base.py +0 -6
  225. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/__init__.py +0 -0
  226. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/my_protocol.py +0 -18
  227. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/CANVAS_MANIFEST.json +0 -29
  228. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/README.md +0 -12
  229. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/__init__.py +0 -0
  230. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/base.py +0 -8
  231. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/__init__.py +0 -0
  232. plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/my_protocol.py +0 -18
  233. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/CANVAS_MANIFEST.json +0 -29
  234. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/README.md +0 -12
  235. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/__init__.py +0 -0
  236. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/base.py +0 -3
  237. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/__init__.py +0 -0
  238. plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/my_protocol.py +0 -18
  239. plugin_runner/tests/fixtures/plugins/test_render_template/CANVAS_MANIFEST.json +0 -47
  240. plugin_runner/tests/fixtures/plugins/test_render_template/README.md +0 -11
  241. plugin_runner/tests/fixtures/plugins/test_render_template/protocols/__init__.py +0 -0
  242. plugin_runner/tests/fixtures/plugins/test_render_template/protocols/my_protocol.py +0 -43
  243. plugin_runner/tests/fixtures/plugins/test_render_template/templates/template.html +0 -10
  244. plugin_runner/tests/fixtures/plugins/test_simple_api/CANVAS_MANIFEST.json +0 -47
  245. plugin_runner/tests/fixtures/plugins/test_simple_api/README.md +0 -11
  246. plugin_runner/tests/fixtures/plugins/test_simple_api/__init__.py +0 -0
  247. plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/__init__.py +0 -0
  248. plugin_runner/tests/fixtures/plugins/test_simple_api/protocols/my_protocol.py +0 -43
  249. plugin_runner/tests/test_application.py +0 -65
  250. plugin_runner/tests/test_plugin_installer.py +0 -127
  251. plugin_runner/tests/test_plugin_runner.py +0 -388
  252. plugin_runner/tests/test_sandbox.py +0 -137
  253. {canvas-0.33.0.dist-info → canvas-0.33.1.dist-info}/WHEEL +0 -0
  254. {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
- import statsd
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
- base_url: str
101
- session: requests.Session
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.base_url, url)
109
+ joined = urllib.parse.urljoin(self._base_url, url)
117
110
 
118
- if not joined.startswith(self.base_url):
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
- super().__setattr__("base_url", base_url)
125
- super().__setattr__("session", requests.Session())
117
+ self._base_url = base_url
118
+ self._session = requests.Session()
126
119
 
127
- self.statsd_client = statsd.StatsClient()
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.session.get(
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.session.post(
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.session.put(
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.session.patch(
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 OntologiesHttp(Http):
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
- # import here to avoid making it exportable to module importers
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(Http):
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
- # import here to avoid making it exportable to module importers
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
- "OntologiesHttp",
267
- "ScienceHttp",
300
+ "ontologies_http",
301
+ "science_http",
268
302
  "batch_get",
269
303
  "batch_post",
270
304
  "batch_put",
271
305
  "batch_patch",
272
- ]
306
+ )
@@ -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
@@ -5,3 +5,6 @@ class CanvasSdkV1Config(AppConfig):
5
5
  """AppConfig for v1 of the SDK data module."""
6
6
 
7
7
  name = "canvas_sdk.v1"
8
+
9
+
10
+ __exports__ = ()
@@ -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
+ )
@@ -77,3 +77,6 @@ class AllergyIntoleranceCoding(models.Model):
77
77
  related_name="codings",
78
78
  null=True,
79
79
  )
80
+
81
+
82
+ __exports__ = ("AllergyIntolerance", "AllergyIntoleranceCoding")
@@ -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
+ )
@@ -38,3 +38,6 @@ class Assessment(models.Model):
38
38
  narrative = models.CharField()
39
39
  background = models.CharField()
40
40
  care_team = models.CharField()
41
+
42
+
43
+ __exports__ = ("AssessmentStatus", "Assessment")
@@ -25,3 +25,6 @@ class BannerAlert(models.Model):
25
25
  intent = models.CharField()
26
26
  href = models.CharField()
27
27
  status = models.CharField()
28
+
29
+
30
+ __exports__ = ("BannerAlert",)
@@ -187,3 +187,6 @@ class ValueSetTimeframeLookupQuerySet(ValueSetLookupQuerySet, TimeframeLookupQue
187
187
  """A class that includes methods for looking up value sets and using timeframes."""
188
188
 
189
189
  pass
190
+
191
+
192
+ __exports__ = ()
@@ -83,3 +83,10 @@ class BillingLineItemModifier(models.Model):
83
83
  related_name="modifiers",
84
84
  null=True,
85
85
  )
86
+
87
+
88
+ __exports__ = (
89
+ "BillingLineItemStatus",
90
+ "BillingLineItem",
91
+ "BillingLineItemModifier",
92
+ )
@@ -58,3 +58,10 @@ class CareTeamMembership(models.Model):
58
58
 
59
59
  def __str__(self) -> str:
60
60
  return f"id={self.id}"
61
+
62
+
63
+ __exports__ = (
64
+ "CareTeamMembershipStatus",
65
+ "CareTeamRole",
66
+ "CareTeamMembership",
67
+ )
@@ -36,3 +36,6 @@ class Command(models.Model):
36
36
  app_label=self._meta.app_label, model_name=self.anchor_object_type
37
37
  )
38
38
  return anchor_model.objects.get(dbid=self.anchor_object_dbid)
39
+
40
+
41
+ __exports__ = ("Command",)
@@ -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
+ )
@@ -76,3 +76,10 @@ class ConditionCoding(models.Model):
76
76
  condition = models.ForeignKey(
77
77
  Condition, on_delete=models.DO_NOTHING, related_name="codings", null=True
78
78
  )
79
+
80
+
81
+ __exports__ = (
82
+ "ClinicalStatus",
83
+ "Condition",
84
+ "ConditionCoding",
85
+ )
@@ -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
+ )
@@ -49,3 +49,6 @@ class DetectedIssueEvidence(models.Model):
49
49
  related_name="evidence",
50
50
  null=True,
51
51
  )
52
+
53
+
54
+ __exports__ = ("DetectedIssue", "DetectedIssueEvidence")
@@ -40,3 +40,6 @@ class Device(models.Model):
40
40
  manufacturing_date = models.DateField()
41
41
  manufacturer = models.CharField()
42
42
  procedure_id = models.BigIntegerField()
43
+
44
+
45
+ __exports__ = ("Device",)
@@ -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
+ )
@@ -72,3 +72,6 @@ class MedicationCoding(models.Model):
72
72
  medication = models.ForeignKey(
73
73
  Medication, on_delete=models.DO_NOTHING, related_name="codings", null=True
74
74
  )
75
+
76
+
77
+ __exports__ = ("Status", "Medication", "MedicationCoding")
@@ -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
+ )
@@ -26,3 +26,6 @@ class Organization(models.Model):
26
26
  group_taxonomy_number = models.CharField()
27
27
  include_zz_qualifier = models.BooleanField()
28
28
  main_location = models.OneToOneField("v1.PracticeLocation", on_delete=models.DO_NOTHING)
29
+
30
+
31
+ __exports__ = ("Organization",)
@@ -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: "RelatedManager[PatientSetting]"
87
+ settings: RelatedManager[PatientSetting]
86
88
 
87
89
  @classmethod
88
- def find(cls, id: str) -> "Patient":
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
+ )
@@ -101,3 +101,10 @@ class PracticeLocationSetting(models.Model):
101
101
 
102
102
  def __str__(self) -> str:
103
103
  return self.name
104
+
105
+
106
+ __exports__ = (
107
+ "PracticeLocationPOS",
108
+ "PracticeLocation",
109
+ "PracticeLocationSetting",
110
+ )
@@ -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") # type: ignore[misc, var-annotated]
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( # type: ignore[var-annotated]
162
+ questionnaires = models.ManyToManyField(
163
163
  Questionnaire,
164
- through="v1.InterviewQuestionnaireMap", # type: ignore[misc]
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
+ )
@@ -20,3 +20,6 @@ class ReasonForVisitSettingCoding(models.Model):
20
20
  version = models.CharField()
21
21
 
22
22
  duration = ArrayField(models.DurationField())
23
+
24
+
25
+ __exports__ = ("ReasonForVisitSettingCoding",)
@@ -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")
@@ -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
+ )
@@ -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", # type: ignore[misc]
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
+ )
@@ -11,3 +11,6 @@ class CanvasUser(models.Model):
11
11
  dbid = models.BigIntegerField(db_column="dbid", primary_key=True)
12
12
  email = models.EmailField(db_column="email")
13
13
  phone_number = models.CharField(db_column="phone_number", max_length=255)
14
+
15
+
16
+ __exports__ = ("CanvasUser",)
canvas_sdk/v1/models.py CHANGED
@@ -2,3 +2,5 @@
2
2
  # reasons. For this reason, we import * from data to avoid duplication.
3
3
 
4
4
  from .data import * # noqa: F403
5
+
6
+ __exports__ = ()
@@ -0,0 +1 @@
1
+ __exports__ = ()