canvas 0.8.0__py3-none-any.whl → 0.8.2__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 (56) hide show
  1. {canvas-0.8.0.dist-info → canvas-0.8.2.dist-info}/METADATA +2 -2
  2. {canvas-0.8.0.dist-info → canvas-0.8.2.dist-info}/RECORD +56 -56
  3. canvas_cli/apps/auth/tests.py +10 -0
  4. canvas_cli/apps/emit/emit.py +0 -1
  5. canvas_cli/apps/logs/logs.py +4 -4
  6. canvas_cli/apps/plugin/plugin.py +55 -43
  7. canvas_cli/apps/plugin/tests.py +4 -2
  8. canvas_cli/conftest.py +1 -0
  9. canvas_cli/main.py +1 -2
  10. canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/my_protocol.py +1 -2
  11. canvas_cli/tests.py +36 -26
  12. canvas_cli/utils/context/context.py +4 -2
  13. canvas_cli/utils/context/tests.py +1 -1
  14. canvas_cli/utils/print/tests.py +2 -2
  15. canvas_cli/utils/validators/tests.py +2 -1
  16. canvas_sdk/base.py +1 -1
  17. canvas_sdk/commands/base.py +4 -6
  18. canvas_sdk/commands/commands/prescribe.py +3 -3
  19. canvas_sdk/commands/commands/reason_for_visit.py +1 -1
  20. canvas_sdk/commands/commands/task.py +3 -2
  21. canvas_sdk/commands/commands/vitals.py +0 -1
  22. canvas_sdk/commands/constants.py +3 -1
  23. canvas_sdk/commands/tests/protocol/tests.py +6 -1
  24. canvas_sdk/commands/tests/schema/tests.py +5 -1
  25. canvas_sdk/commands/tests/test_utils.py +27 -12
  26. canvas_sdk/commands/tests/unit/tests.py +3 -0
  27. canvas_sdk/effects/__init__.py +2 -0
  28. canvas_sdk/effects/banner_alert/__init__.py +2 -0
  29. canvas_sdk/effects/banner_alert/tests.py +22 -14
  30. canvas_sdk/effects/protocol_card/__init__.py +2 -0
  31. canvas_sdk/effects/protocol_card/tests.py +10 -6
  32. canvas_sdk/events/__init__.py +2 -0
  33. canvas_sdk/handlers/__init__.py +2 -0
  34. canvas_sdk/protocols/__init__.py +2 -0
  35. canvas_sdk/protocols/base.py +0 -2
  36. canvas_sdk/protocols/clinical_quality_measure.py +2 -1
  37. canvas_sdk/utils/http.py +2 -1
  38. canvas_sdk/utils/tests.py +4 -0
  39. canvas_sdk/v1/data/__init__.py +13 -0
  40. canvas_sdk/v1/data/allergy_intolerance.py +0 -1
  41. canvas_sdk/v1/data/base.py +5 -5
  42. canvas_sdk/v1/data/billing.py +2 -2
  43. canvas_sdk/v1/data/common.py +0 -1
  44. canvas_sdk/v1/data/patient.py +1 -1
  45. canvas_sdk/v1/data/questionnaire.py +2 -1
  46. canvas_sdk/value_set/custom.py +0 -10
  47. canvas_sdk/value_set/tests/test_value_sets.py +4 -0
  48. canvas_sdk/value_set/v2022/individual_characteristic.py +12 -6
  49. canvas_sdk/value_set/v2022/procedure.py +4 -2
  50. canvas_sdk/value_set/value_set.py +1 -1
  51. plugin_runner/plugin_runner.py +4 -3
  52. plugin_runner/sandbox.py +6 -8
  53. plugin_runner/tests/test_plugin_runner.py +1 -2
  54. settings.py +3 -1
  55. {canvas-0.8.0.dist-info → canvas-0.8.2.dist-info}/WHEEL +0 -0
  56. {canvas-0.8.0.dist-info → canvas-0.8.2.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,9 @@
1
1
  import shutil
2
+ from collections.abc import Generator
2
3
  from contextlib import chdir
3
4
  from datetime import datetime
4
5
  from pathlib import Path
5
- from typing import Any, Generator
6
+ from typing import Any
6
7
 
7
8
  import pytest
8
9
  import requests
@@ -21,6 +22,7 @@ runner = CliRunner()
21
22
 
22
23
  @pytest.fixture(scope="session")
23
24
  def token() -> MaskedValue:
25
+ """Get a valid token."""
24
26
  return MaskedValue(
25
27
  requests.post(
26
28
  f"{settings.INTEGRATION_TEST_URL}/auth/token/",
@@ -36,6 +38,7 @@ def token() -> MaskedValue:
36
38
 
37
39
  @pytest.fixture(scope="session")
38
40
  def first_patient_id(token: MaskedValue) -> dict:
41
+ """Get the first patient id."""
39
42
  headers = {
40
43
  "Authorization": f"Bearer {token.value}",
41
44
  "Content-Type": "application/json",
@@ -47,6 +50,7 @@ def first_patient_id(token: MaskedValue) -> dict:
47
50
 
48
51
  @pytest.fixture(scope="session")
49
52
  def plugin_name() -> str:
53
+ """Get the plugin name to be used."""
50
54
  return f"addbanneralert{datetime.now().timestamp()}".replace(".", "")
51
55
 
52
56
 
@@ -54,7 +58,7 @@ def plugin_name() -> str:
54
58
  def write_and_install_protocol_and_clean_up(
55
59
  first_patient_id: str, plugin_name: str, token: MaskedValue
56
60
  ) -> Generator[Any, Any, Any]:
57
-
61
+ """Write the protocol code, install the plugin, and clean up after the test."""
58
62
  if not settings.INTEGRATION_TEST_URL:
59
63
  raise ImproperlyConfigured("INTEGRATION_TEST_URL is not set")
60
64
 
@@ -62,9 +66,8 @@ def write_and_install_protocol_and_clean_up(
62
66
  with chdir(Path("./custom-plugins")):
63
67
  runner.invoke(app, "init", input=plugin_name)
64
68
 
65
- protocol = open(f"./custom-plugins/{plugin_name}/protocols/my_protocol.py", "w")
66
- protocol.write(
67
- f"""from canvas_sdk.effects.banner_alert import AddBannerAlert
69
+ protocol_code = f"""
70
+ from canvas_sdk.effects.banner_alert import AddBannerAlert
68
71
  from canvas_sdk.events import EventType
69
72
  from canvas_sdk.protocols import BaseProtocol
70
73
 
@@ -81,16 +84,18 @@ class Protocol(BaseProtocol):
81
84
  ).apply()
82
85
  ]
83
86
  """
84
- )
85
- protocol.close()
86
87
 
87
- # install the plugin
88
- requests.post(
89
- plugin_url(settings.INTEGRATION_TEST_URL),
90
- data={"is_enabled": True},
91
- files={"package": open(_build_package(Path(f"./custom-plugins/{plugin_name}")), "rb")},
92
- headers={"Authorization": f"Bearer {token.value}"},
93
- )
88
+ with open(f"./custom-plugins/{plugin_name}/protocols/my_protocol.py", "w") as protocol:
89
+ protocol.write(protocol_code)
90
+
91
+ with open(_build_package(Path(f"./custom-plugins/{plugin_name}")), "rb") as package:
92
+ # install the plugin
93
+ requests.post(
94
+ plugin_url(settings.INTEGRATION_TEST_URL),
95
+ data={"is_enabled": True},
96
+ files={"package": package},
97
+ headers={"Authorization": f"Bearer {token.value}"},
98
+ )
94
99
 
95
100
  yield
96
101
 
@@ -132,6 +137,7 @@ def test_protocol_that_adds_banner_alert(
132
137
  plugin_name: str,
133
138
  first_patient_id: str,
134
139
  ) -> None:
140
+ """Test that the protocol adds a banner alert."""
135
141
  # trigger the event
136
142
  requests.post(
137
143
  f"{settings.INTEGRATION_TEST_URL}/api/Note/",
@@ -206,6 +212,7 @@ def test_protocol_that_adds_banner_alert(
206
212
  def test_banner_alert_apply_method_succeeds_with_all_required_fields(
207
213
  Effect: type[AddBannerAlert] | type[RemoveBannerAlert], params: dict, expected_payload: str
208
214
  ) -> None:
215
+ """Test that the apply method succeeds with all required fields."""
209
216
  b = Effect()
210
217
  for k, v in params.items():
211
218
  setattr(b, k, v)
@@ -240,6 +247,7 @@ def test_banner_alert_apply_method_succeeds_with_all_required_fields(
240
247
  def test_banner_alert_apply_method_raises_error_without_required_fields(
241
248
  Effect: type[AddBannerAlert] | type[RemoveBannerAlert], expected_err_msgs: str
242
249
  ) -> None:
250
+ """Test that the apply method raises an error when missing required fields."""
243
251
  b = Effect()
244
252
  with pytest.raises(ValidationError) as e:
245
253
  b.apply()
@@ -1 +1,3 @@
1
1
  from canvas_sdk.effects.protocol_card.protocol_card import ProtocolCard, Recommendation
2
+
3
+ __all__ = ("ProtocolCard", "Recommendation")
@@ -21,6 +21,7 @@ from canvas_sdk.effects.protocol_card import ProtocolCard, Recommendation
21
21
 
22
22
 
23
23
  def test_apply_method_succeeds_with_patient_id_and_key() -> None:
24
+ """Test that the apply method succeeds with all required fields."""
24
25
  p = ProtocolCard(patient_id="uuid", key="something-unique")
25
26
  applied = p.apply()
26
27
  assert (
@@ -30,6 +31,7 @@ def test_apply_method_succeeds_with_patient_id_and_key() -> None:
30
31
 
31
32
 
32
33
  def test_apply_method_raises_error_without_patient_id_and_key() -> None:
34
+ """Test that the apply method raises an error when missing required fields."""
33
35
  p = ProtocolCard()
34
36
 
35
37
  with pytest.raises(ValidationError) as e:
@@ -109,6 +111,7 @@ def test_apply_method_raises_error_without_patient_id_and_key() -> None:
109
111
  def test_add_recommendations(
110
112
  init_params: dict[Any, Any], rec1_params: dict[Any, Any], rec2_params: dict[Any, Any]
111
113
  ) -> None:
114
+ """Test that the add_recommendation method adds recommendations to the ProtocolCard."""
112
115
  p = ProtocolCard(**init_params)
113
116
  p.add_recommendation(**rec1_params)
114
117
  p.recommendations.append(Recommendation(**rec2_params))
@@ -117,17 +120,17 @@ def test_add_recommendations(
117
120
  "narrative": init_params["narrative"],
118
121
  "recommendations": [
119
122
  {
120
- "title": rec1_params.get("title", None),
121
- "button": rec1_params.get("button", None),
122
- "href": rec1_params.get("href", None),
123
+ "title": rec1_params.get("title"),
124
+ "button": rec1_params.get("button"),
125
+ "href": rec1_params.get("href"),
123
126
  "command": {"type": rec1_params["command"]} if "command" in rec1_params else {},
124
127
  "context": rec1_params.get("context", {}),
125
128
  "key": 0,
126
129
  },
127
130
  {
128
- "title": rec2_params.get("title", None),
129
- "button": rec2_params.get("button", None),
130
- "href": rec2_params.get("href", None),
131
+ "title": rec2_params.get("title"),
132
+ "button": rec2_params.get("button"),
133
+ "href": rec2_params.get("href"),
131
134
  "command": {"type": rec2_params["command"]} if "command" in rec2_params else {},
132
135
  "context": rec2_params.get("context", {}),
133
136
  "key": 1,
@@ -158,6 +161,7 @@ def test_add_recommendations(
158
161
  def test_add_recommendations_from_commands(
159
162
  Command: type[_BaseCommand], init_params: dict[str, str]
160
163
  ) -> None:
164
+ """Test that the add_recommendation method adds recommendations from commands to the ProtocolCard."""
161
165
  cmd = Command(**init_params)
162
166
  p = ProtocolCard(patient_id="uuid", key="commands")
163
167
  p.recommendations.append(cmd.recommend())
@@ -1 +1,3 @@
1
1
  from canvas_generated.messages.events_pb2 import Event, EventResponse, EventType
2
+
3
+ __all__ = ("Event", "EventResponse", "EventType")
@@ -1 +1,3 @@
1
1
  from canvas_sdk.handlers.base import BaseHandler
2
+
3
+ __all__ = ("BaseHandler",)
@@ -1,2 +1,4 @@
1
1
  from canvas_sdk.protocols.base import BaseProtocol
2
2
  from canvas_sdk.protocols.clinical_quality_measure import ClinicalQualityMeasure
3
+
4
+ __all__ = ("BaseProtocol", "ClinicalQualityMeasure")
@@ -1,5 +1,3 @@
1
- from typing import Any
2
-
3
1
  from canvas_sdk.handlers.base import BaseHandler
4
2
 
5
3
 
@@ -88,7 +88,8 @@ class ClinicalQualityMeasure(BaseProtocol):
88
88
  case EventType.CONDITION_CREATED | EventType.CONDITION_UPDATED:
89
89
  self._patient_id = patient_id(Condition)
90
90
  case (
91
- EventType.MEDICATION_LIST_ITEM_CREATED | EventType.MEDICATION_LIST_ITEM_UPDATED
91
+ EventType.MEDICATION_LIST_ITEM_CREATED
92
+ | EventType.MEDICATION_LIST_ITEM_UPDATED
92
93
  ):
93
94
  self._patient_id = patient_id(Medication)
94
95
  case _:
canvas_sdk/utils/http.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import time
2
+ from collections.abc import Callable, Mapping
2
3
  from functools import wraps
3
- from typing import Any, Callable, Mapping, TypeVar, cast
4
+ from typing import Any, TypeVar, cast
4
5
 
5
6
  import requests
6
7
  import statsd
canvas_sdk/utils/tests.py CHANGED
@@ -5,6 +5,7 @@ from canvas_sdk.utils import Http
5
5
 
6
6
  @patch("requests.Session.get")
7
7
  def test_http_get(mock_get: MagicMock) -> None:
8
+ """Test that the Http.get method calls requests.get with the correct arguments."""
8
9
  http = Http()
9
10
  http.get("https://www.canvasmedical.com/", headers={"Authorization": "Bearer as;ldkfjdkj"})
10
11
  mock_get.assert_called_once_with(
@@ -14,6 +15,7 @@ def test_http_get(mock_get: MagicMock) -> None:
14
15
 
15
16
  @patch("requests.Session.post")
16
17
  def test_http_post(mock_post: MagicMock) -> None:
18
+ """Test that the Http.post method calls requests.post with the correct arguments."""
17
19
  http = Http()
18
20
  http.post(
19
21
  "https://www.canvasmedical.com/",
@@ -31,6 +33,7 @@ def test_http_post(mock_post: MagicMock) -> None:
31
33
 
32
34
  @patch("requests.Session.put")
33
35
  def test_http_put(mock_put: MagicMock) -> None:
36
+ """Test that the Http.put method calls requests.put with the correct arguments."""
34
37
  http = Http()
35
38
  http.put(
36
39
  "https://www.canvasmedical.com/",
@@ -48,6 +51,7 @@ def test_http_put(mock_put: MagicMock) -> None:
48
51
 
49
52
  @patch("requests.Session.patch")
50
53
  def test_http_patch(mock_patch: MagicMock) -> None:
54
+ """Test that the Http.patch method calls requests.patch with the correct arguments."""
51
55
  http = Http()
52
56
  http.patch(
53
57
  "https://www.canvasmedical.com/",
@@ -4,3 +4,16 @@ from .medication import Medication, MedicationCoding
4
4
  from .patient import Patient
5
5
  from .staff import Staff
6
6
  from .task import Task, TaskComment, TaskLabel
7
+
8
+ __all__ = (
9
+ "BillingLineItem",
10
+ "Condition",
11
+ "ConditionCoding",
12
+ "Medication",
13
+ "MedicationCoding",
14
+ "Patient",
15
+ "Staff",
16
+ "Task",
17
+ "TaskComment",
18
+ "TaskLabel",
19
+ )
@@ -1,4 +1,3 @@
1
- from django.contrib.postgres.fields import ArrayField
2
1
  from django.db import models
3
2
 
4
3
  from canvas_sdk.v1.data.base import CommittableModelManager, ValueSetLookupQuerySet
@@ -1,6 +1,6 @@
1
1
  from abc import abstractmethod
2
2
  from collections.abc import Container
3
- from typing import TYPE_CHECKING, Any, Protocol, Self, Type, cast
3
+ from typing import TYPE_CHECKING, Any, Protocol, Self, cast
4
4
 
5
5
  from django.db import models
6
6
  from django.db.models import Q
@@ -50,7 +50,7 @@ class ValueSetLookupQuerySetProtocol(QuerySetProtocol):
50
50
 
51
51
  @staticmethod
52
52
  @abstractmethod
53
- def codings(value_set: Type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
53
+ def codings(value_set: type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
54
54
  """A protocol method for defining codings."""
55
55
  raise NotImplementedError
56
56
 
@@ -64,7 +64,7 @@ class ValueSetLookupQuerySetProtocol(QuerySetProtocol):
64
64
  class ValueSetLookupQuerySetMixin(ValueSetLookupQuerySetProtocol):
65
65
  """A QuerySet mixin that can filter objects based on a ValueSet."""
66
66
 
67
- def find(self, value_set: Type["ValueSet"]) -> models.QuerySet[Any]:
67
+ def find(self, value_set: type["ValueSet"]) -> models.QuerySet[Any]:
68
68
  """
69
69
  Filters conditions, medications, etc. to those found in the inherited ValueSet class that is passed.
70
70
 
@@ -84,7 +84,7 @@ class ValueSetLookupQuerySetMixin(ValueSetLookupQuerySetProtocol):
84
84
  return self.filter(q_filter).distinct()
85
85
 
86
86
  @staticmethod
87
- def codings(value_set: Type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
87
+ def codings(value_set: type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
88
88
  """Provide a sequence of tuples where each tuple is a code system URL and a set of codes."""
89
89
  values_dict = cast(dict, value_set.values)
90
90
  return cast(
@@ -113,7 +113,7 @@ class ValueSetLookupByNameQuerySetMixin(ValueSetLookupQuerySetMixin):
113
113
  """
114
114
 
115
115
  @staticmethod
116
- def codings(value_set: Type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
116
+ def codings(value_set: type["ValueSet"]) -> tuple[tuple[str, set[str]]]:
117
117
  """
118
118
  Provide a sequence of tuples where each tuple is a code system name and a set of codes.
119
119
  """
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Type
1
+ from typing import TYPE_CHECKING
2
2
 
3
3
  from django.db import models
4
4
 
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
14
14
  class BillingLineItemQuerySet(ValueSetTimeframeLookupQuerySet):
15
15
  """A class that adds functionality to filter BillingLineItem objects."""
16
16
 
17
- def find(self, value_set: Type["ValueSet"]) -> models.QuerySet:
17
+ def find(self, value_set: type["ValueSet"]) -> models.QuerySet:
18
18
  """
19
19
  This method is overridden to use for BillingLineItem CPT codes.
20
20
  The codes are saved as string values in the BillingLineItem.cpt field,
@@ -1,4 +1,3 @@
1
- from django.contrib.postgres.fields import ArrayField
2
1
  from django.db import models
3
2
 
4
3
 
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Self
1
+ from typing import Self
2
2
 
3
3
  import arrow
4
4
  from django.db import models
@@ -153,7 +153,8 @@ class Interview(models.Model):
153
153
  note_id = models.BigIntegerField()
154
154
  appointment_id = models.BigIntegerField()
155
155
  questionnaires = models.ManyToManyField( # type: ignore[var-annotated]
156
- Questionnaire, through="canvas_sdk.InterviewQuestionnaireMap" # type: ignore[misc]
156
+ Questionnaire,
157
+ through="canvas_sdk.InterviewQuestionnaireMap", # type: ignore[misc]
157
158
  )
158
159
  progress_status = models.CharField()
159
160
  created = models.DateTimeField()
@@ -115,7 +115,6 @@ class Antiarrhythmics(ValueSet):
115
115
  "230155",
116
116
  "237183",
117
117
  "243776",
118
- "243776",
119
118
  "248491",
120
119
  "248829",
121
120
  "250272",
@@ -129,9 +128,6 @@ class Antiarrhythmics(ValueSet):
129
128
  "265785",
130
129
  "274471",
131
130
  "278255",
132
- "278255",
133
- "278255",
134
- "278255",
135
131
  "280333",
136
132
  "281153",
137
133
  "283306",
@@ -139,8 +135,6 @@ class Antiarrhythmics(ValueSet):
139
135
  "291187",
140
136
  "296991",
141
137
  "444249",
142
- "444249",
143
- "444944",
144
138
  "444944",
145
139
  "449494",
146
140
  "449496",
@@ -157,12 +151,10 @@ class Antiarrhythmics(ValueSet):
157
151
  "454207",
158
152
  "454371",
159
153
  "545231",
160
- "545231",
161
154
  "545232",
162
155
  "545233",
163
156
  "545238",
164
157
  "545239",
165
- "545239",
166
158
  "558741",
167
159
  "558745",
168
160
  "559416",
@@ -177,8 +169,6 @@ class Antiarrhythmics(ValueSet):
177
169
  "565069",
178
170
  "573523",
179
171
  "583982",
180
- "583982",
181
- "583985",
182
172
  "583985",
183
173
  "590326",
184
174
  "590375",
@@ -8,12 +8,14 @@ from canvas_sdk.value_set.value_set import CombinedValueSet
8
8
 
9
9
 
10
10
  def test_value_set_class_values_property() -> None:
11
+ """Test that the value_set returns the correct values."""
11
12
  value_set = DisordersOfTheImmuneSystem
12
13
  assert value_set.values["ICD10CM"] == DisordersOfTheImmuneSystem.ICD10CM
13
14
  assert value_set.values["SNOMEDCT"] == DisordersOfTheImmuneSystem.SNOMEDCT
14
15
 
15
16
 
16
17
  def test_value_set_class_pipe_operator_with_two_value_sets() -> None:
18
+ """Test that the pipe operator returns the correct values."""
17
19
  combined_value_set: CombinedValueSet = (
18
20
  DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination
19
21
  )
@@ -30,6 +32,7 @@ def test_value_set_class_pipe_operator_with_two_value_sets() -> None:
30
32
 
31
33
 
32
34
  def test_value_set_class_pipe_operator_with_three_value_sets() -> None:
35
+ """Test that the pipe operator returns the correct values with multiple operands."""
33
36
  combined_value_set: CombinedValueSet = (
34
37
  DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination | Rhabdomyolysis
35
38
  )
@@ -46,6 +49,7 @@ def test_value_set_class_pipe_operator_with_three_value_sets() -> None:
46
49
 
47
50
 
48
51
  def test_value_set_class_pipe_operator_with_two_combined_value_sets() -> None:
52
+ """Test that the pipe operator returns the correct values with two combined value_sets."""
49
53
  combined_value_set_1: CombinedValueSet = (
50
54
  DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination
51
55
  )
@@ -2,7 +2,8 @@ from ..value_set import ValueSet
2
2
 
3
3
 
4
4
  class Ethnicity(ValueSet):
5
- """
5
+ """Ethnicity value set.
6
+
6
7
  **Clinical Focus:**
7
8
 
8
9
  **Data Element Scope:**
@@ -26,7 +27,8 @@ class Ethnicity(ValueSet):
26
27
 
27
28
 
28
29
  class OncAdministrativeSex(ValueSet):
29
- """
30
+ """ONC Administrative Sex value set.
31
+
30
32
  **Clinical Focus:** Gender identity restricted to only Male and Female used in administrative situations requiring a restriction to these two categories.
31
33
 
32
34
  **Data Element Scope:** Gender
@@ -50,7 +52,8 @@ class OncAdministrativeSex(ValueSet):
50
52
 
51
53
 
52
54
  class Payer(ValueSet):
53
- """
55
+ """Payer value set.
56
+
54
57
  **Clinical Focus:** Categories of types of health care payor entities as defined by the US Public Health Data Consortium SOP code system
55
58
 
56
59
  **Data Element Scope:** @code in CCDA r2.1 template Planned Coverage [act: identifier urn:oid:2.16.840.1.113883.10.20.22.4.129 (open)] DYNAMIC
@@ -234,7 +237,8 @@ class Payer(ValueSet):
234
237
 
235
238
 
236
239
  class Race(ValueSet):
237
- """
240
+ """Race value set.
241
+
238
242
  **Clinical Focus:**
239
243
 
240
244
  **Data Element Scope:**
@@ -262,7 +266,8 @@ class Race(ValueSet):
262
266
 
263
267
 
264
268
  class Female(ValueSet):
265
- """
269
+ """Female Gender value set.
270
+
266
271
  **Clinical Focus:** Concepts that represent Female when assessing quality measures
267
272
 
268
273
  **Data Element Scope:** Gender
@@ -285,7 +290,8 @@ class Female(ValueSet):
285
290
 
286
291
 
287
292
  class White(ValueSet):
288
- """
293
+ """White Race value set.
294
+
289
295
  **Clinical Focus:** The purpose of this value set is to represent concepts for the patient characteristic of white race.
290
296
 
291
297
  **Data Element Scope:** This value set may use a model element related to Race.
@@ -1563,7 +1563,8 @@ class PeritonealDialysis(ValueSet):
1563
1563
 
1564
1564
 
1565
1565
  class ProceduresUsedToIndicateSexualActivity(ValueSet):
1566
- """
1566
+ """Procedures Used to Indicate Sexual Activity Value Set.
1567
+
1567
1568
  **Clinical Focus:** The purpose of this value set is to represent procedures indicating history of sexual activity
1568
1569
 
1569
1570
  **Data Element Scope:** This value set may use a model element related to Procedure.
@@ -2514,7 +2515,8 @@ class CabgSurgeries(ValueSet):
2514
2515
 
2515
2516
 
2516
2517
  class Cabg_PciProcedure(ValueSet):
2517
- """
2518
+ """CABG, PCI Procedure Value Set.
2519
+
2518
2520
  **Clinical Focus:** CABG and PCI procedures
2519
2521
 
2520
2522
  **Data Element Scope:** CABG and PCI procedures
@@ -107,6 +107,6 @@ class ValueSet(CodeConstantsURLMappingMixin, metaclass=ValueSystems):
107
107
  """A property that returns a dictionary of code systems and their associated values."""
108
108
  return {
109
109
  system: getattr(cls, system)
110
- for system in cls.CODE_SYSTEM_MAPPING.keys()
110
+ for system in cls.CODE_SYSTEM_MAPPING
111
111
  if hasattr(cls, system)
112
112
  }
@@ -8,8 +8,9 @@ import sys
8
8
  import time
9
9
  import traceback
10
10
  from collections import defaultdict
11
+ from collections.abc import AsyncGenerator
11
12
  from types import FrameType
12
- from typing import Any, AsyncGenerator, Optional, TypedDict
13
+ from typing import Any, TypedDict
13
14
 
14
15
  import grpc
15
16
  import statsd
@@ -181,7 +182,7 @@ class PluginRunner(PluginRunnerServicer):
181
182
  yield ReloadPluginsResponse(success=True)
182
183
 
183
184
 
184
- def handle_hup_cb(_signum: int, _frame: Optional[FrameType]) -> None:
185
+ def handle_hup_cb(_signum: int, _frame: FrameType | None) -> None:
185
186
  """handle_hup_cb."""
186
187
  log.info("Received SIGHUP, reloading plugins...")
187
188
  load_plugins()
@@ -191,7 +192,7 @@ def find_modules(base_path: pathlib.Path, prefix: str | None = None) -> list[str
191
192
  """Find all modules in the specified package path."""
192
193
  modules: list[str] = []
193
194
 
194
- for file_finder, module_name, is_pkg in pkgutil.iter_modules(
195
+ for _, module_name, is_pkg in pkgutil.iter_modules(
195
196
  [base_path.as_posix()],
196
197
  ):
197
198
  if is_pkg:
plugin_runner/sandbox.py CHANGED
@@ -141,13 +141,12 @@ class Sandbox:
141
141
  ):
142
142
  self.warn(
143
143
  node,
144
- '"{name}" is an invalid variable name because it '
145
- 'starts with "_"'.format(name=name),
144
+ f'"{name}" is an invalid variable name because it ' 'starts with "_"',
146
145
  )
147
146
  elif name.endswith("__roles__"):
148
147
  self.error(
149
148
  node,
150
- '"%s" is an invalid variable name because ' 'it ends with "__roles__".' % name,
149
+ f'"{name}" is an invalid variable name because ' 'it ends with "__roles__".',
151
150
  )
152
151
  elif name in FORBIDDEN_FUNC_NAMES:
153
152
  self.error(node, f'"{name}" is a reserved name.')
@@ -166,15 +165,14 @@ class Sandbox:
166
165
  if node.attr.startswith("_") and node.attr != "_":
167
166
  self.warn(
168
167
  node,
169
- '"{name}" is an invalid attribute name because it starts '
170
- 'with "_".'.format(name=node.attr),
168
+ f'"{node.attr}" is an invalid attribute name because it starts ' 'with "_".',
171
169
  )
172
170
 
173
171
  if node.attr.endswith("__roles__"):
174
172
  self.error(
175
173
  node,
176
- '"{name}" is an invalid attribute name because it ends '
177
- 'with "__roles__".'.format(name=node.attr),
174
+ f'"{node.attr}" is an invalid attribute name because it ends '
175
+ 'with "__roles__".',
178
176
  )
179
177
 
180
178
  if isinstance(node.ctx, ast.Load):
@@ -188,7 +186,7 @@ class Sandbox:
188
186
  copy_locations(new_node, node)
189
187
  return new_node
190
188
 
191
- elif isinstance(node.ctx, (ast.Store, ast.Del)):
189
+ elif isinstance(node.ctx, ast.Store | ast.Del):
192
190
  node = self.node_contents_visit(node)
193
191
  new_value = ast.Call(
194
192
  func=ast.Name("_write_", ast.Load()), args=[node.value], keywords=[]
@@ -1,6 +1,6 @@
1
1
  import shutil
2
+ from collections.abc import Generator
2
3
  from pathlib import Path
3
- from typing import Generator
4
4
  from unittest.mock import MagicMock, patch
5
5
 
6
6
  import pytest
@@ -179,7 +179,6 @@ async def test_reload_plugins_event_handler_successfully_loads_plugins(
179
179
  setup_test_plugin: Path, plugin_runner: PluginRunner
180
180
  ) -> None:
181
181
  """Test ReloadPlugins Event handler successfully loads plugins."""
182
-
183
182
  with patch("plugin_runner.plugin_runner.publish_message", MagicMock()) as mock_publish_message:
184
183
  request = ReloadPluginsRequest()
185
184
 
settings.py CHANGED
@@ -57,7 +57,9 @@ PLUGIN_DIRECTORY = os.getenv(
57
57
  (
58
58
  "/plugin-runner/custom-plugins"
59
59
  if IS_PRODUCTION
60
- else "./plugin_runner/tests/data/plugins" if IS_TESTING else "./custom-plugins"
60
+ else "./plugin_runner/tests/data/plugins"
61
+ if IS_TESTING
62
+ else "./custom-plugins"
61
63
  ),
62
64
  )
63
65
 
File without changes