Skip to content

Commit 4bec539

Browse files
jens-kuertenJens Kürten
andauthored
Feat: Add MyPy support (#20)
* add mypy * mark package as typed --------- Co-authored-by: Jens Kürten <[email protected]>
1 parent ec1886e commit 4bec539

16 files changed

+73
-81
lines changed

.pre-commit-config.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ repos:
1111
args: [ --fix ]
1212
# Run the formatter.
1313
- id: ruff-format
14-
14+
- repo: https://github.com/pre-commit/mirrors-mypy
15+
rev: 'v1.15.0'
16+
hooks:
17+
- id: mypy
18+
additional_dependencies:
19+
[
20+
types-mock,
21+
types-requests,
22+
types-PyYAML,
23+
pydantic
24+
]
1525
- repo: https://github.com/pre-commit/pre-commit-hooks
1626
rev: v4.4.0
1727
hooks:

csfunctions/actions/dummy.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,4 @@ class DummyAction(BaseAction):
88
Dummy Action, for unit testing
99
"""
1010

11-
def __init__(self, id: str, **kwargs): # pylint: disable=redefined-builtin
12-
super().__init__(name=ActionNames.DUMMY, id=id, data=kwargs["data"])
13-
14-
name: Literal[ActionNames.DUMMY]
11+
name: Literal[ActionNames.DUMMY] = ActionNames.DUMMY

csfunctions/events/dummy.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,5 @@ class DummyEvent(BaseEvent):
1717
Dummy Event, for unit testing
1818
"""
1919

20-
def __init__(self, event_id: str, data: DummyEventData, **_):
21-
super().__init__(name=EventNames.DUMMY, event_id=event_id, data=data)
22-
23-
name: Literal[EventNames.DUMMY]
24-
data: DummyEventData = Field([])
20+
name: Literal[EventNames.DUMMY] = EventNames.DUMMY
21+
data: DummyEventData = Field(..., description="Dummy Event Data")

csfunctions/events/workflow_task_trigger.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,5 @@ class WorkflowTaskTriggerEventData(BaseModel):
1818

1919

2020
class WorkflowTaskTriggerEvent(BaseEvent):
21-
def __init__(self, event_id: str, data: WorkflowTaskTriggerEventData, **_):
22-
super().__init__(name=EventNames.WORKFLOW_TASK_TRIGGER, event_id=event_id, data=data)
23-
24-
name: Literal[EventNames.WORKFLOW_TASK_TRIGGER]
21+
name: Literal[EventNames.WORKFLOW_TASK_TRIGGER] = EventNames.WORKFLOW_TASK_TRIGGER
2522
data: WorkflowTaskTriggerEventData

csfunctions/handler.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
from typing import Callable
77

88
import yaml
9-
from pydantic import BaseModel
109

1110
from csfunctions import ErrorResponse, Event, Request, WorkloadResponse
1211
from csfunctions.actions import ActionUnion
1312
from csfunctions.config import ConfigModel, FunctionModel
13+
from csfunctions.events import EventData
1414
from csfunctions.objects import BaseObject
1515
from csfunctions.response import ResponseUnion
1616
from csfunctions.service import Service
@@ -31,7 +31,7 @@ def _get_function(function_name: str, function_dir: str) -> FunctionModel:
3131
config = _load_config(function_dir)
3232
func = next(func for func in config.functions if func.name == function_name)
3333
if not func:
34-
raise ValueError(f"Could not find function with name { function_name} in the environment.yaml.")
34+
raise ValueError(f"Could not find function with name {function_name} in the environment.yaml.")
3535
return func
3636

3737

@@ -53,7 +53,7 @@ def link_objects(event: Event):
5353
e.g. document.part
5454
"""
5555
data = getattr(event, "data", None)
56-
if not isinstance(data, BaseModel):
56+
if data is None or not isinstance(data, EventData): # type: ignore # MyPy doesn't like PEP604
5757
return
5858

5959
# we expect all objects to be passed in Event.data
@@ -81,24 +81,26 @@ def execute(function_name: str, request_body: str, function_dir: str = "src") ->
8181
try:
8282
request = Request(**json.loads(request_body))
8383
link_objects(request.event)
84+
8485
function_callback = get_function_callable(function_name, function_dir)
85-
service = Service(str(request.metadata.service_url), request.metadata.service_token)
86+
service = Service(
87+
str(request.metadata.service_url) if request.metadata.service_url else None, request.metadata.service_token
88+
)
8689

8790
response = function_callback(request.metadata, request.event, service)
8891

8992
if response is None:
9093
return ""
9194

92-
if isinstance(response, ActionUnion):
95+
if isinstance(response, ActionUnion): # type: ignore # MyPy doesn't like PEP604
9396
# wrap returned Actions into a WorkloadResponse
9497
response = WorkloadResponse(actions=[response])
95-
elif isinstance(response, list) and all(isinstance(o, ActionUnion) for o in response):
98+
elif isinstance(response, list) and all(isinstance(o, ActionUnion) for o in response): # type: ignore # MyPy doesn't like PEP604
9699
# wrap list of Actions into a WorkloadResponse
97100
response = WorkloadResponse(actions=response)
98101

99-
if not isinstance(
100-
response, ResponseUnion
101-
): # need to check for ResponseUnion instead of Response, because isinstance doesn't work with annotated unions
102+
if not isinstance(response, ResponseUnion): # type: ignore # MyPy doesn't like PEP604
103+
# need to check for ResponseUnion instead of Response, because isinstance doesn't work with annotated unions
102104
raise ValueError("Function needs to return a Response object or None.")
103105

104106
# make sure the event_id is filled out correctly

csfunctions/metadata.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,10 @@
11
from datetime import datetime
2+
from typing import Optional
23

34
from pydantic import AnyHttpUrl, BaseModel, Field
45

56

67
class MetaData(BaseModel):
7-
def __init__(
8-
self,
9-
app_lang: str,
10-
app_user: str,
11-
request_id: str,
12-
request_datetime: datetime,
13-
transaction_id: str,
14-
instance_url: str,
15-
db_service_url: str | None = None,
16-
**kwargs,
17-
):
18-
super().__init__(
19-
app_lang=app_lang,
20-
app_user=app_user,
21-
request_id=request_id,
22-
db_service_url=db_service_url,
23-
request_datetime=request_datetime,
24-
transaction_id=transaction_id,
25-
instance_url=instance_url,
26-
**kwargs,
27-
)
28-
298
app_lang: str = Field(..., description="ISO code of the session language that triggered the webhook.")
309
app_user: str = Field(..., description="User id of the user that triggered the webhook. (personalnummer)")
3110
request_id: str = Field(..., description="Unique identifier of this request.")
@@ -34,6 +13,6 @@ def __init__(
3413
request_datetime: datetime = Field(..., description="Time when the request was started.")
3514
transaction_id: str = Field(..., description="Unique identifier of the transaction.")
3615
instance_url: AnyHttpUrl = Field(..., description="URL to the instance where the webhook was triggered.")
37-
db_service_url: AnyHttpUrl | None = Field(
16+
db_service_url: Optional[AnyHttpUrl] = Field(
3817
None, description="URL to the DB Access Service responsible for the instance."
3918
)

csfunctions/objects/classification.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ class ObjectPropertyValue(BaseObject):
1616
ref_object_id: str = Field(..., description="Referenced Object")
1717
boolean_value: int | None = Field(..., description="Boolean Value")
1818
datetime_value: datetime | None = Field(..., description="Datetime Value")
19-
float_value: float | None = Field("", description="Float Value")
20-
float_value_normalized: float | None = Field("", description="Float Value Normalized")
21-
integer_value: int | None = Field("", description="Integer Value")
19+
float_value: float | None = Field(None, description="Float Value")
20+
float_value_normalized: float | None = Field(None, description="Float Value Normalized")
21+
integer_value: int | None = Field(None, description="Integer Value")
2222
iso_language_code: str | None = Field(None, description="ISO Language Code")
23-
value_pos: int | None = Field("", description="Position")
23+
value_pos: int | None = Field(None, description="Position")
2424
property_code: str | None = Field("", description="Property Code")
2525
property_path: str | None = Field(None, description="Property Path")
2626
property_type: str | None = Field(None, description="Property Type")

csfunctions/objects/document.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,4 @@ class CADDocument(Document):
9898
Special Document type that contains a CAD-Model.
9999
"""
100100

101-
object_type: Literal[ObjectType.CAD_DOCUMENT] = ObjectType.CAD_DOCUMENT
101+
object_type: Literal[ObjectType.CAD_DOCUMENT] = ObjectType.CAD_DOCUMENT # type: ignore[assignment]

csfunctions/objects/workflow.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ class Workflow(BaseObject):
2525
global_briefcases: list[Briefcase] = Field([], exclude=True)
2626

2727
def link_objects(self, data: "EventData"):
28-
local_briefcases = getattr(data, "local_briefcases", None)
29-
global_briefcases = getattr(data, "local_briefcases", None)
28+
local_briefcases: list[Briefcase] | None = getattr(data, "local_briefcases", None)
29+
global_briefcases: list[Briefcase] | None = getattr(data, "local_briefcases", None)
3030

3131
if local_briefcases and self.local_briefcase_ids:
3232
self._link_local_briefcases(local_briefcases)
3333

3434
if global_briefcases and self.global_briefcase_ids:
35-
self._link_global_briefcases(local_briefcases)
35+
self._link_global_briefcases(global_briefcases)
3636

3737
def _link_local_briefcases(self, local_briefcases: list["Briefcase"]):
3838
for local_briefcase in local_briefcases:

csfunctions/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)