Browse Source

Use callback for context and fix wrong class usage

Bastien Sevajol 6 years ago
parent
commit
83f2903db9
4 changed files with 32 additions and 17 deletions
  1. 10 4
      hapic/decorator.py
  2. 20 11
      hapic/hapic.py
  3. 1 1
      hapic/processor.py
  4. 1 1
      setup.py

+ 10 - 4
hapic/decorator.py View File

@@ -54,16 +54,22 @@ class ControllerWrapper(object):
54 54
 class InputOutputControllerWrapper(ControllerWrapper):
55 55
     def __init__(
56 56
         self,
57
-        context: ContextInterface,
57
+        context: typing.Union[ContextInterface, typing.Callable[[], ContextInterface]],  # nopep8
58 58
         processor: ProcessorInterface,
59 59
         error_http_code: HTTPStatus=HTTPStatus.BAD_REQUEST,
60 60
         default_http_code: HTTPStatus=HTTPStatus.OK,
61 61
     ) -> None:
62
-        self.context = context
62
+        self._context = context
63 63
         self.processor = processor
64 64
         self.error_http_code = error_http_code
65 65
         self.default_http_code = default_http_code
66 66
 
67
+    @property
68
+    def context(self) -> ContextInterface:
69
+        if callable(self._context):
70
+            return self._context()
71
+        return self._context
72
+
67 73
 
68 74
 class InputControllerWrapper(InputOutputControllerWrapper):
69 75
     def before_wrapped_func(
@@ -140,7 +146,7 @@ class InputControllerWrapper(InputOutputControllerWrapper):
140 146
 class OutputControllerWrapper(InputOutputControllerWrapper):
141 147
     def __init__(
142 148
         self,
143
-        context: ContextInterface,
149
+        context: typing.Union[ContextInterface, typing.Callable[[], ContextInterface]],  # nopep8
144 150
         processor: ProcessorInterface,
145 151
         error_http_code: HTTPStatus=HTTPStatus.INTERNAL_SERVER_ERROR,
146 152
         default_http_code: HTTPStatus=HTTPStatus.OK,
@@ -294,7 +300,7 @@ class ExceptionHandlerControllerWrapper(ControllerWrapper):
294 300
     def __init__(
295 301
         self,
296 302
         handled_exception_class: typing.Type[Exception],
297
-        context: ContextInterface,
303
+        context: typing.Union[ContextInterface, typing.Callable[[], ContextInterface]],  # nopep8
298 304
         http_code: HTTPStatus=HTTPStatus.INTERNAL_SERVER_ERROR,
299 305
     ) -> None:
300 306
         self.handled_exception_class = handled_exception_class

+ 20 - 11
hapic/hapic.py View File

@@ -27,6 +27,7 @@ from hapic.description import OutputHeadersDescription
27 27
 from hapic.doc import DocGenerator
28 28
 from hapic.processor import ProcessorInterface
29 29
 from hapic.processor import MarshmallowInputProcessor
30
+from hapic.processor import MarshmallowOutputProcessor
30 31
 
31 32
 # TODO: Gérer les erreurs avec schema
32 33
 # TODO: Gérer les erreurs avec schema: pouvoir le spécialiser
@@ -50,6 +51,15 @@ class Hapic(object):
50 51
         self._buffer = DecorationBuffer()
51 52
         self._controllers = []  # type: typing.List[DecoratedController]
52 53
         self._context = None
54
+
55
+        # This local function will be pass to different components
56
+        # who will need context but declared (like with decorator)
57
+        # before context declaration
58
+        def context_getter():
59
+            return self._context
60
+
61
+        self._context_getter = context_getter
62
+
53 63
         # TODO: Permettre la surcharge des classes utilisés ci-dessous
54 64
 
55 65
     def with_api_doc(self):
@@ -86,10 +96,9 @@ class Hapic(object):
86 96
         error_http_code: HTTPStatus = HTTPStatus.BAD_REQUEST,
87 97
         default_http_code: HTTPStatus = HTTPStatus.OK,
88 98
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
89
-        processor = processor or MarshmallowInputProcessor()
99
+        processor = processor or MarshmallowOutputProcessor()
90 100
         processor.schema = schema
91
-        context = context or self._context
92
-
101
+        context = context or self._context_getter
93 102
         decoration = OutputBodyControllerWrapper(
94 103
             context=context,
95 104
             processor=processor,
@@ -110,9 +119,9 @@ class Hapic(object):
110 119
         error_http_code: HTTPStatus = HTTPStatus.BAD_REQUEST,
111 120
         default_http_code: HTTPStatus = HTTPStatus.OK,
112 121
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
113
-        processor = processor or MarshmallowInputProcessor()
122
+        processor = processor or MarshmallowOutputProcessor()
114 123
         processor.schema = schema
115
-        context = context or self._context
124
+        context = context or self._context_getter
116 125
 
117 126
         decoration = OutputHeadersControllerWrapper(
118 127
             context=context,
@@ -136,7 +145,7 @@ class Hapic(object):
136 145
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
137 146
         processor = processor or MarshmallowInputProcessor()
138 147
         processor.schema = schema
139
-        context = context or self._context
148
+        context = context or self._context_getter
140 149
 
141 150
         decoration = InputHeadersControllerWrapper(
142 151
             context=context,
@@ -160,7 +169,7 @@ class Hapic(object):
160 169
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
161 170
         processor = processor or MarshmallowInputProcessor()
162 171
         processor.schema = schema
163
-        context = context or self._context
172
+        context = context or self._context_getter
164 173
 
165 174
         decoration = InputPathControllerWrapper(
166 175
             context=context,
@@ -184,7 +193,7 @@ class Hapic(object):
184 193
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
185 194
         processor = processor or MarshmallowInputProcessor()
186 195
         processor.schema = schema
187
-        context = context or self._context
196
+        context = context or self._context_getter
188 197
 
189 198
         decoration = InputQueryControllerWrapper(
190 199
             context=context,
@@ -208,7 +217,7 @@ class Hapic(object):
208 217
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
209 218
         processor = processor or MarshmallowInputProcessor()
210 219
         processor.schema = schema
211
-        context = context or self._context
220
+        context = context or self._context_getter
212 221
 
213 222
         decoration = InputBodyControllerWrapper(
214 223
             context=context,
@@ -232,7 +241,7 @@ class Hapic(object):
232 241
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
233 242
         processor = processor or MarshmallowInputProcessor()
234 243
         processor.schema = schema
235
-        context = context or self._context
244
+        context = context or self._context_getter
236 245
 
237 246
         decoration = InputBodyControllerWrapper(
238 247
             context=context,
@@ -252,7 +261,7 @@ class Hapic(object):
252 261
         http_code: HTTPStatus = HTTPStatus.INTERNAL_SERVER_ERROR,
253 262
         context: ContextInterface = None,
254 263
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
255
-        context = context or self._context
264
+        context = context or self._context_getter
256 265
 
257 266
         decoration = ExceptionHandlerControllerWrapper(
258 267
             handled_exception_class,

+ 1 - 1
hapic/processor.py View File

@@ -76,7 +76,7 @@ class MarshmallowOutputProcessor(OutputProcessor):
76 76
         )
77 77
 
78 78
 
79
-class MarshmallowInputProcessor(OutputProcessor):
79
+class MarshmallowInputProcessor(InputProcessor):
80 80
     def process(self, data: dict):
81 81
         unmarshall = self.schema.load(data)
82 82
         if unmarshall.errors:

+ 1 - 1
setup.py View File

@@ -23,7 +23,7 @@ setup(
23 23
     # Versions should comply with PEP440.  For a discussion on single-sourcing
24 24
     # the version across setup.py and the project code, see
25 25
     # https://packaging.python.org/en/latest/single_source_version.html
26
-    version='0.0.2.3',
26
+    version='0.0.3',
27 27
 
28 28
     description='HTTP api input/output manager',
29 29
     # long_description=long_description,