Browse Source

more generic useable

Bastien Sevajol 6 years ago
parent
commit
9e99b350ba
5 changed files with 46 additions and 30 deletions
  1. 6 1
      example_a.py
  2. 13 15
      hapic/__init__.py
  3. 3 0
      hapic/context.py
  4. 1 0
      hapic/doc.py
  5. 23 14
      hapic/hapic.py

+ 6 - 1
example_a.py View File

12
 from hapic.data import HapicData
12
 from hapic.data import HapicData
13
 
13
 
14
 app = bottle.Bottle()
14
 app = bottle.Bottle()
15
+# hapic.global_exception_handler(UnAuthExc, StandardErrorSchema)
16
+# hapic.global_exception_handler(UnAuthExc2, StandardErrorSchema)
17
+# hapic.global_exception_handler(UnAuthExc3, StandardErrorSchema)
18
+bottle.default_app.push(app)
19
+hapic.set_context(hapic.ext.bottle.bottle_context)
15
 
20
 
16
 
21
 
17
 def bob(f):
22
 def bob(f):
95
 # print(yaml.dump(ss, default_flow_style=False))
100
 # print(yaml.dump(ss, default_flow_style=False))
96
 # time.sleep(1)
101
 # time.sleep(1)
97
 
102
 
98
-print(json.dumps(hapic.generate_doc(app)))
103
+print(json.dumps(hapic.generate_doc()))
99
 
104
 
100
 app.run(host='localhost', port=8080, debug=True)
105
 app.run(host='localhost', port=8080, debug=True)

+ 13 - 15
hapic/__init__.py View File

1
 # -*- coding: utf-8 -*-
1
 # -*- coding: utf-8 -*-
2
+from hapic.context import BottleContext
2
 from hapic.hapic import Hapic
3
 from hapic.hapic import Hapic
3
 
4
 
4
 _hapic_default = Hapic()
5
 _hapic_default = Hapic()
13
 output_body = _hapic_default.output_body
14
 output_body = _hapic_default.output_body
14
 # with_api_doc_bis = _hapic_default.with_api_doc_bis
15
 # with_api_doc_bis = _hapic_default.with_api_doc_bis
15
 generate_doc = _hapic_default.generate_doc
16
 generate_doc = _hapic_default.generate_doc
17
+set_context = _hapic_default.set_context
16
 handle_exception = _hapic_default.handle_exception
18
 handle_exception = _hapic_default.handle_exception
17
 
19
 
18
 # from hapic.hapic import with_api_doc
20
 # from hapic.hapic import with_api_doc
28
 # from hapic.hapic import error_schema
30
 # from hapic.hapic import error_schema
29
 
31
 
30
 
32
 
31
-# class FakeSetContext(object):
32
-#     def bottle_context(self):
33
-#         hapic.set_fake_default_context(BottleContext())
34
-#         def decorator(func):
35
-#             def wrapper(*args, **kwargs):
36
-#                 return func(*args, **kwargs)
37
-#             return wrapper
38
-#         return decorator
39
-#
40
-#
41
-# class FakeExt(object):
42
-#     bottle = FakeSetContext()
43
-#
44
-#
45
-# ext = FakeExt()
33
+class FakeSetContext(object):
34
+    @property
35
+    def bottle_context(self):
36
+        return BottleContext()
37
+
38
+
39
+class FakeExt(object):
40
+    bottle = FakeSetContext()
41
+
42
+
43
+ext = FakeExt()

+ 3 - 0
hapic/context.py View File

76
             status=int(http_code),
76
             status=int(http_code),
77
         )
77
         )
78
 
78
 
79
+    # FIXME: Pas generique
80
+    def get_app(self):
81
+        return bottle.default_app()

+ 1 - 0
hapic/doc.py View File

61
     # jsonschema based
61
     # jsonschema based
62
     if description.input_path:
62
     if description.input_path:
63
         schema_class = type(description.input_path.wrapper.processor.schema)
63
         schema_class = type(description.input_path.wrapper.processor.schema)
64
+        # TODO: look schema2parameters ?
64
         jsonschema = schema2jsonschema(schema_class, spec=spec)
65
         jsonschema = schema2jsonschema(schema_class, spec=spec)
65
         for name, schema in jsonschema.get('properties', {}).items():
66
         for name, schema in jsonschema.get('properties', {}).items():
66
             method_operations.setdefault('parameters', []).append({
67
             method_operations.setdefault('parameters', []).append({

+ 23 - 14
hapic/hapic.py View File

26
 from hapic.processor import ProcessorInterface
26
 from hapic.processor import ProcessorInterface
27
 from hapic.processor import MarshmallowInputProcessor
27
 from hapic.processor import MarshmallowInputProcessor
28
 
28
 
29
-# TODO: Gérer les erreurs de schema
29
+# TODO: Gérer les erreurs avec schema
30
+# TODO: Gérer les erreurs avec schema: pouvoir le spécialiser
30
 # TODO: Gérer les cas ou c'est une liste la réponse (items, item_nb)
31
 # TODO: Gérer les cas ou c'est une liste la réponse (items, item_nb)
31
 # TODO: Confusion nommage body/json/forms
32
 # TODO: Confusion nommage body/json/forms
32
 
33
 
33
 # _waiting = {}
34
 # _waiting = {}
34
 # _endpoints = {}
35
 # _endpoints = {}
35
-# TODO NOW: C'est un gros gros fake !
36
+# FIXME: Voir
36
 class ErrorResponseSchema(marshmallow.Schema):
37
 class ErrorResponseSchema(marshmallow.Schema):
37
     error_message = marshmallow.fields.String(required=True)
38
     error_message = marshmallow.fields.String(required=True)
38
-    error_details = marshmallow.fields.Dict(required=True)
39
 
39
 
40
-_default_global_context = BottleContext()
40
+
41
+    error_details = marshmallow.fields.Dict(required=True)
42
+# FIXME: C'est un gros gros fake !
41
 _default_global_error_schema = ErrorResponseSchema()
43
 _default_global_error_schema = ErrorResponseSchema()
42
 
44
 
43
 
45
 
45
     def __init__(self):
47
     def __init__(self):
46
         self._buffer = DecorationBuffer()
48
         self._buffer = DecorationBuffer()
47
         self._controllers = []  # type: typing.List[DecoratedController]
49
         self._controllers = []  # type: typing.List[DecoratedController]
50
+        self._context = None
48
         # TODO: Permettre la surcharge des classes utilisés ci-dessous
51
         # TODO: Permettre la surcharge des classes utilisés ci-dessous
49
 
52
 
50
     def with_api_doc(self):
53
     def with_api_doc(self):
65
 
68
 
66
         return decorator
69
         return decorator
67
 
70
 
71
+    def set_context(self, context: ContextInterface) -> None:
72
+        assert not self._context
73
+        self._context = context
74
+
68
     def output_body(
75
     def output_body(
69
         self,
76
         self,
70
         schema: typing.Any,
77
         schema: typing.Any,
75
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
82
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
76
         processor = processor or MarshmallowInputProcessor()
83
         processor = processor or MarshmallowInputProcessor()
77
         processor.schema = schema
84
         processor.schema = schema
78
-        context = context or _default_global_context
85
+        context = context or self._context
79
 
86
 
80
         decoration = OutputBodyControllerWrapper(
87
         decoration = OutputBodyControllerWrapper(
81
             context=context,
88
             context=context,
99
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
106
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
100
         processor = processor or MarshmallowInputProcessor()
107
         processor = processor or MarshmallowInputProcessor()
101
         processor.schema = schema
108
         processor.schema = schema
102
-        context = context or _default_global_context
109
+        context = context or self._context
103
 
110
 
104
         decoration = OutputHeadersControllerWrapper(
111
         decoration = OutputHeadersControllerWrapper(
105
             context=context,
112
             context=context,
123
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
130
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
124
         processor = processor or MarshmallowInputProcessor()
131
         processor = processor or MarshmallowInputProcessor()
125
         processor.schema = schema
132
         processor.schema = schema
126
-        context = context or _default_global_context
133
+        context = context or self._context
127
 
134
 
128
         decoration = InputHeadersControllerWrapper(
135
         decoration = InputHeadersControllerWrapper(
129
             context=context,
136
             context=context,
147
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
154
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
148
         processor = processor or MarshmallowInputProcessor()
155
         processor = processor or MarshmallowInputProcessor()
149
         processor.schema = schema
156
         processor.schema = schema
150
-        context = context or _default_global_context
157
+        context = context or self._context
151
 
158
 
152
         decoration = InputPathControllerWrapper(
159
         decoration = InputPathControllerWrapper(
153
             context=context,
160
             context=context,
171
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
178
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
172
         processor = processor or MarshmallowInputProcessor()
179
         processor = processor or MarshmallowInputProcessor()
173
         processor.schema = schema
180
         processor.schema = schema
174
-        context = context or _default_global_context
181
+        context = context or self._context
175
 
182
 
176
         decoration = InputQueryControllerWrapper(
183
         decoration = InputQueryControllerWrapper(
177
             context=context,
184
             context=context,
195
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
202
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
196
         processor = processor or MarshmallowInputProcessor()
203
         processor = processor or MarshmallowInputProcessor()
197
         processor.schema = schema
204
         processor.schema = schema
198
-        context = context or _default_global_context
205
+        context = context or self._context
199
 
206
 
200
         decoration = InputBodyControllerWrapper(
207
         decoration = InputBodyControllerWrapper(
201
             context=context,
208
             context=context,
219
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
226
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
220
         processor = processor or MarshmallowInputProcessor()
227
         processor = processor or MarshmallowInputProcessor()
221
         processor.schema = schema
228
         processor.schema = schema
222
-        context = context or _default_global_context
229
+        context = context or self._context
223
 
230
 
224
         decoration = InputBodyControllerWrapper(
231
         decoration = InputBodyControllerWrapper(
225
             context=context,
232
             context=context,
239
         http_code: HTTPStatus = HTTPStatus.INTERNAL_SERVER_ERROR,
246
         http_code: HTTPStatus = HTTPStatus.INTERNAL_SERVER_ERROR,
240
         context: ContextInterface = None,
247
         context: ContextInterface = None,
241
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
248
     ) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Any]:
242
-        context = context or _default_global_context
249
+        context = context or self._context
243
 
250
 
244
         decoration = ExceptionHandlerControllerWrapper(
251
         decoration = ExceptionHandlerControllerWrapper(
245
             handled_exception_class,
252
             handled_exception_class,
252
             return decoration.get_wrapper(func)
259
             return decoration.get_wrapper(func)
253
         return decorator
260
         return decorator
254
 
261
 
255
-    def generate_doc(self, app=None):
256
-        # TODO @Damien bottle specific code !
262
+    def generate_doc(self):
263
+        # FIXME @Damien bottle specific code !
264
+        # rendre ca generique
265
+        app = self._context.get_app()
257
         doc_generator = DocGenerator()
266
         doc_generator = DocGenerator()
258
         return doc_generator.get_doc(self._controllers, app)
267
         return doc_generator.get_doc(self._controllers, app)