canvas 0.5.0__py3-none-any.whl → 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of canvas might be problematic. Click here for more details.
- {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/METADATA +4 -3
- {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/RECORD +32 -31
- canvas_generated/messages/events_pb2.py +2 -2
- canvas_generated/messages/events_pb2.pyi +4 -0
- canvas_sdk/base.py +12 -9
- canvas_sdk/commands/base.py +2 -1
- canvas_sdk/effects/banner_alert/add_banner_alert.py +13 -2
- canvas_sdk/effects/banner_alert/remove_banner_alert.py +2 -2
- canvas_sdk/effects/banner_alert/tests.py +20 -4
- canvas_sdk/effects/base.py +2 -0
- canvas_sdk/effects/protocol_card/protocol_card.py +9 -2
- canvas_sdk/effects/protocol_card/tests.py +3 -3
- canvas_sdk/effects/task/task.py +99 -0
- canvas_sdk/protocols/base.py +1 -11
- canvas_sdk/protocols/clinical_quality_measure.py +57 -1
- canvas_sdk/protocols/timeframe.py +39 -0
- canvas_sdk/v1/data/__init__.py +3 -0
- canvas_sdk/v1/data/base.py +95 -12
- canvas_sdk/v1/data/billing.py +59 -0
- canvas_sdk/v1/data/common.py +58 -0
- canvas_sdk/v1/data/condition.py +18 -2
- canvas_sdk/v1/data/medication.py +11 -3
- canvas_sdk/v1/data/note.py +161 -0
- canvas_sdk/v1/data/patient.py +19 -1
- canvas_sdk/v1/data/protocol_override.py +1 -1
- canvas_sdk/v1/data/staff.py +65 -0
- canvas_sdk/v1/data/task.py +112 -0
- canvas_sdk/value_set/custom.py +984 -0
- canvas_sdk/value_set/value_set.py +4 -1
- plugin_runner/sandbox.py +3 -0
- canvas_sdk/data/__init__.py +0 -1
- canvas_sdk/data/base.py +0 -26
- canvas_sdk/data/client.py +0 -82
- canvas_sdk/data/patient.py +0 -8
- canvas_sdk/data/staff.py +0 -8
- canvas_sdk/data/task.py +0 -67
- {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/WHEEL +0 -0
- {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/entry_points.txt +0 -0
|
@@ -8,6 +8,7 @@ class CodeConstants:
|
|
|
8
8
|
"""A class representing different code systems and their URLs."""
|
|
9
9
|
|
|
10
10
|
CPT = "CPT"
|
|
11
|
+
HCPCS = "HCPCS"
|
|
11
12
|
HCPCSLEVELII = "HCPCSLEVELII"
|
|
12
13
|
CVX = "CVX"
|
|
13
14
|
LOINC = "LOINC"
|
|
@@ -22,6 +23,7 @@ class CodeConstants:
|
|
|
22
23
|
NDC = "NDC"
|
|
23
24
|
|
|
24
25
|
URL_CPT = "http://www.ama-assn.org/go/cpt"
|
|
26
|
+
URL_HCPCS = "http://www.cms.gov/medicare/coding/medhcpcsgeninfo"
|
|
25
27
|
URL_HCPCSLEVELII = "https://coder.aapc.com/hcpcs-codes"
|
|
26
28
|
URL_CVX = "http://hl7.org/fhir/sid/cvx"
|
|
27
29
|
URL_LOINC = "http://loinc.org"
|
|
@@ -40,6 +42,7 @@ class CodeConstantsURLMappingMixin:
|
|
|
40
42
|
|
|
41
43
|
CODE_SYSTEM_MAPPING = {
|
|
42
44
|
CodeConstants.CPT: CodeConstants.URL_CPT,
|
|
45
|
+
CodeConstants.HCPCS: CodeConstants.URL_HCPCS,
|
|
43
46
|
CodeConstants.HCPCSLEVELII: CodeConstants.URL_HCPCSLEVELII,
|
|
44
47
|
CodeConstants.CVX: CodeConstants.URL_CVX,
|
|
45
48
|
CodeConstants.LOINC: CodeConstants.URL_LOINC,
|
|
@@ -100,7 +103,7 @@ class ValueSet(CodeConstantsURLMappingMixin, metaclass=ValueSystems):
|
|
|
100
103
|
"""The Base class for a ValueSet."""
|
|
101
104
|
|
|
102
105
|
@classproperty
|
|
103
|
-
def values(cls) -> dict[str, set]:
|
|
106
|
+
def values(cls) -> dict[str, set[str]]:
|
|
104
107
|
"""A property that returns a dictionary of code systems and their associated values."""
|
|
105
108
|
return {
|
|
106
109
|
system: getattr(cls, system)
|
plugin_runner/sandbox.py
CHANGED
|
@@ -48,6 +48,8 @@ ALLOWED_MODULES = frozenset(
|
|
|
48
48
|
"contextlib",
|
|
49
49
|
"datetime",
|
|
50
50
|
"dateutil",
|
|
51
|
+
"django.db.models",
|
|
52
|
+
"django.utils.functional",
|
|
51
53
|
"enum",
|
|
52
54
|
"functools",
|
|
53
55
|
"hashlib",
|
|
@@ -59,6 +61,7 @@ ALLOWED_MODULES = frozenset(
|
|
|
59
61
|
"operator",
|
|
60
62
|
"pickletools",
|
|
61
63
|
"random",
|
|
64
|
+
"rapidfuzz",
|
|
62
65
|
"re",
|
|
63
66
|
"requests",
|
|
64
67
|
"string",
|
canvas_sdk/data/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .base import DataModel
|
canvas_sdk/data/base.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
from pydantic_core import ValidationError
|
|
4
|
-
|
|
5
|
-
from canvas_sdk.base import Model
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DataModel(Model):
|
|
9
|
-
"""Base class for data models."""
|
|
10
|
-
|
|
11
|
-
class Meta:
|
|
12
|
-
update_required_fields = ("id",)
|
|
13
|
-
|
|
14
|
-
def model_dump_json_nested(self, *args: Any, **kwargs: Any) -> str:
|
|
15
|
-
"""
|
|
16
|
-
Returns the model's json representation nested in a {"data": {..}} key.
|
|
17
|
-
"""
|
|
18
|
-
return f'{{"data": {self.model_dump_json(*args, **kwargs)}}}'
|
|
19
|
-
|
|
20
|
-
def _validate_before_effect(self, method: str) -> None:
|
|
21
|
-
if method == "create" and getattr(self, "id", None):
|
|
22
|
-
error = self._create_error_detail(
|
|
23
|
-
"value", "create cannot be called on a model with an id", "id"
|
|
24
|
-
)
|
|
25
|
-
raise ValidationError.from_exception_data(self.__class__.__name__, [error])
|
|
26
|
-
super()._validate_before_effect(method)
|
canvas_sdk/data/client.py
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
from typing import Any, cast
|
|
2
|
-
|
|
3
|
-
from gql import Client, gql
|
|
4
|
-
from gql.transport.aiohttp import AIOHTTPTransport
|
|
5
|
-
|
|
6
|
-
from settings import GRAPHQL_ENDPOINT
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class _CanvasGQLClient:
|
|
10
|
-
"""
|
|
11
|
-
This is a GraphQL client that can be used to query home-app in order to fetch data for use in plugins.
|
|
12
|
-
|
|
13
|
-
Usage Examples:
|
|
14
|
-
|
|
15
|
-
A query with no parameters:
|
|
16
|
-
|
|
17
|
-
TEST_QUERY_NO_PARAMS = '''
|
|
18
|
-
query PatientsAll {
|
|
19
|
-
patients {
|
|
20
|
-
edges {
|
|
21
|
-
node {
|
|
22
|
-
firstName
|
|
23
|
-
lastName
|
|
24
|
-
birthDate
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
'''
|
|
30
|
-
|
|
31
|
-
client = _CanvasGQLClient()
|
|
32
|
-
result = client.query(TEST_QUERY_NO_PARAMS)
|
|
33
|
-
print(result) # returns dictionary
|
|
34
|
-
|
|
35
|
-
A query with parameters:
|
|
36
|
-
|
|
37
|
-
TEST_QUERY_WITH_PARAMS = '''
|
|
38
|
-
query PatientGet($patientKey: String!) {
|
|
39
|
-
patient(patientKey: $patientKey) {
|
|
40
|
-
firstName
|
|
41
|
-
lastName
|
|
42
|
-
birthDate
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
'''
|
|
46
|
-
|
|
47
|
-
client = _CanvasGQLClient()
|
|
48
|
-
result = client.query(TEST_QUERY_NO_PARAMS)
|
|
49
|
-
print(result)
|
|
50
|
-
|
|
51
|
-
For use in plugins, it is included in the instantiation of Protocol class. This means
|
|
52
|
-
it can simply be referred to as self.client in plugin code.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
def __init__(self) -> None:
|
|
56
|
-
self.client = Client(
|
|
57
|
-
transport=AIOHTTPTransport(url=GRAPHQL_ENDPOINT),
|
|
58
|
-
# TODO: follow the documentation in the link below to specify a
|
|
59
|
-
# cached copy of the schema
|
|
60
|
-
# https://gql.readthedocs.io/en/stable/usage/validation.html#using-a-provided-schema
|
|
61
|
-
fetch_schema_from_transport=False,
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
def query(
|
|
65
|
-
self,
|
|
66
|
-
gql_query: str,
|
|
67
|
-
variables: dict[str, Any] | None = None,
|
|
68
|
-
extra_args: dict[str, Any] | None = None,
|
|
69
|
-
) -> dict[str, Any]:
|
|
70
|
-
if variables is None:
|
|
71
|
-
query_variables = {}
|
|
72
|
-
else:
|
|
73
|
-
query_variables = variables
|
|
74
|
-
|
|
75
|
-
return self.client.execute(
|
|
76
|
-
gql(gql_query),
|
|
77
|
-
variable_values=query_variables,
|
|
78
|
-
extra_args=extra_args,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
GQL_CLIENT = _CanvasGQLClient()
|
canvas_sdk/data/patient.py
DELETED
canvas_sdk/data/staff.py
DELETED
canvas_sdk/data/task.py
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from enum import Enum
|
|
3
|
-
|
|
4
|
-
from canvas_sdk.data import DataModel
|
|
5
|
-
from canvas_sdk.data.patient import Patient
|
|
6
|
-
from canvas_sdk.data.staff import Staff
|
|
7
|
-
from canvas_sdk.effects import Effect, EffectType
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Task(DataModel):
|
|
11
|
-
"""Data model for a task."""
|
|
12
|
-
|
|
13
|
-
class Meta(DataModel.Meta):
|
|
14
|
-
create_required_fields = ("title",)
|
|
15
|
-
|
|
16
|
-
class Status(Enum):
|
|
17
|
-
COMPLETED = "Completed"
|
|
18
|
-
CLOSED = "Closed"
|
|
19
|
-
OPEN = "Open"
|
|
20
|
-
|
|
21
|
-
id: str | None = None
|
|
22
|
-
assignee: Staff | None = None
|
|
23
|
-
patient: Patient | None = None
|
|
24
|
-
title: str | None = None
|
|
25
|
-
due: datetime | None = None
|
|
26
|
-
status: Status | None = None
|
|
27
|
-
comments: "list[TaskComment] | None" = None
|
|
28
|
-
labels: list[str] | None = None
|
|
29
|
-
|
|
30
|
-
def create(self) -> Effect:
|
|
31
|
-
"""Return an effect to create the task."""
|
|
32
|
-
self._validate_before_effect("create")
|
|
33
|
-
return Effect(type=EffectType.CREATE_TASK, payload=self.model_dump_json_nested())
|
|
34
|
-
|
|
35
|
-
def update(self) -> Effect:
|
|
36
|
-
"""Return an effect to update the task."""
|
|
37
|
-
self._validate_before_effect("update")
|
|
38
|
-
payload = self.model_dump_json_nested(exclude_unset=True)
|
|
39
|
-
return Effect(type=EffectType.UPDATE_TASK, payload=payload)
|
|
40
|
-
|
|
41
|
-
def add_comment(self, comment: str) -> Effect:
|
|
42
|
-
"""Return an effect to add a comment to the task."""
|
|
43
|
-
if not self.id:
|
|
44
|
-
raise ValueError("Cannot add a comment to a Task without an id")
|
|
45
|
-
task_comment = TaskComment(task=self, body=comment)
|
|
46
|
-
task_comment._validate_before_effect("create")
|
|
47
|
-
return Effect(
|
|
48
|
-
type=EffectType.CREATE_TASK_COMMENT,
|
|
49
|
-
payload=task_comment.model_dump_json_nested(exclude_unset=True),
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class TaskComment(DataModel):
|
|
54
|
-
"""Data model for a task comment."""
|
|
55
|
-
|
|
56
|
-
class Meta:
|
|
57
|
-
create_required_fields = (
|
|
58
|
-
"body",
|
|
59
|
-
"task",
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
id: str | None = None
|
|
63
|
-
task: Task | None = None
|
|
64
|
-
body: str | None = None
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Task.model_rebuild()
|
|
File without changes
|
|
File without changes
|