Skip to content

Commit 8353bcb

Browse files
committed
Linting and typing fixes
The main change is that I've had to add a decorator to keep mypy happy when we add attributes to functions. This is a known issue: python/mypy#2087
1 parent 38fb5ca commit 8353bcb

File tree

7 files changed

+34
-14
lines changed

7 files changed

+34
-14
lines changed

src/labthings/apispec/plugins.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class MarshmallowPlugin(_MarshmallowPlugin):
5454

5555
class FlaskLabThingsPlugin(BasePlugin):
5656
"""APIspec plugin for Flask LabThings"""
57+
5758
spec = None
5859

5960
def init_spec(self, spec):

src/labthings/default_views/actions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
from ..find import current_labthing
55
from ..marshalling import use_args
66
from ..schema import ActionSchema
7-
from ..views import View
7+
from ..views import View, described_operation
88

99

1010
class ActionQueueView(View):
1111
"""List of all actions from the session"""
1212

13+
@described_operation
1314
def get(self):
1415
"""Action queue
1516
@@ -49,6 +50,7 @@ class ActionObjectView(View):
4950

5051
parameters = [TASK_ID_PARAMETER]
5152

53+
@described_operation
5254
def get(self, task_id):
5355
"""Show the status of an Action
5456
@@ -73,6 +75,7 @@ def get(self, task_id):
7375
"404": {"description": "Action not found"},
7476
}
7577

78+
@described_operation
7679
@use_args({"timeout": fields.Int()})
7780
def delete(self, args, task_id):
7881
"""Cancel a running Action

src/labthings/default_views/extensions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"""Top-level representation of attached and enabled Extensions"""
22
from ..find import registered_extensions
33
from ..schema import ExtensionSchema
4-
from ..views import View
4+
from ..views import View, described_operation
55

66

77
class ExtensionList(View):
88
"""List and basic documentation for all enabled Extensions"""
99

1010
tags = ["extensions"]
1111

12+
@described_operation
1213
def get(self):
1314
"""List enabled extensions.
1415

src/labthings/default_views/root.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from ..find import current_labthing
2-
from ..views import View
2+
from ..views import View, described_operation
33

44

55
class RootView(View):
66
"""W3C Thing Description"""
77

8+
@described_operation
89
def get(self):
910
"""Thing Description
1011
---

src/labthings/schema.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,19 +172,17 @@ def build_action_schema(
172172
if not name.endswith("Action"):
173173
name = f"{name}Action"
174174

175-
class GenSchema(base_class):
176-
pass
175+
class_attrs: Dict[str, Union[fields.Nested, fields.Field, str]] = {}
177176

178-
GenSchema.__name__ = name
179-
GenSchema.__doc__ = (
180-
f"Description of an action, with specific parameters for `{name}`"
181-
)
177+
class_attrs[
178+
"__doc__"
179+
] = f"Description of an action, with specific parameters for `{name}`"
182180
if input_schema:
183-
GenSchema.input = nest_if_needed(input_schema)
181+
class_attrs["input"] = nest_if_needed(input_schema)
184182
if output_schema:
185-
GenSchema.output = nest_if_needed(output_schema)
183+
class_attrs["output"] = nest_if_needed(output_schema)
186184

187-
return GenSchema
185+
return type(name, (base_class,), class_attrs)
188186

189187

190188
def openapi_array(schema: FuzzySchemaType) -> Dict:

src/labthings/views/__init__.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
from collections import OrderedDict
3-
from typing import Dict, List, Optional, Set
3+
from typing import Callable, Dict, List, Optional, Set, cast
4+
from typing_extensions import Protocol
45

56
from flask import request
67
from flask.views import MethodView
@@ -25,6 +26,18 @@
2526
OptionalSchema = Optional[FuzzySchemaType]
2627

2728

29+
class DescribedOperation(Protocol):
30+
summary: str
31+
description: str
32+
parameters: List
33+
responses: Dict
34+
35+
36+
def described_operation(func: Callable) -> DescribedOperation:
37+
"""Add type information so mypy permits us to use attributes"""
38+
return cast(DescribedOperation, func)
39+
40+
2841
class View(MethodView):
2942
"""A LabThing Resource class should make use of functions
3043
get(), put(), post(), and delete(), corresponding to HTTP methods.
@@ -168,6 +181,7 @@ def __init_subclass__(cls):
168181
"""
169182
cls._deque = Deque() # Action queue
170183

184+
@described_operation
171185
@classmethod
172186
def get(cls):
173187
"""
@@ -285,6 +299,7 @@ class EventView(View):
285299
_cls_tags = {"events"}
286300
_deque = Deque() # Action queue
287301

302+
@described_operation
288303
@classmethod
289304
def get(cls):
290305
"""

src/labthings/views/builder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Type
55

66
from flask import abort, send_file
7-
from . import View
7+
from . import View, described_operation
88

99

1010
def static_from(static_folder: str, name=None) -> Type[View]:
@@ -19,6 +19,7 @@ def static_from(static_folder: str, name=None) -> Type[View]:
1919
name = f"static-{uid}"
2020

2121
# Create inner functions
22+
@described_operation
2223
def _get(_, path=""):
2324
"""
2425
:param path: (Default value = "")

0 commit comments

Comments
 (0)