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,6 +12,11 @@ from example import HelloResponseSchema, HelloPathSchema, HelloJsonSchema, \
12 12
 from hapic.data import HapicData
13 13
 
14 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 22
 def bob(f):
@@ -95,6 +100,6 @@ app.route('/hello3/<name>', callback=hello3)
95 100
 # print(yaml.dump(ss, default_flow_style=False))
96 101
 # time.sleep(1)
97 102
 
98
-print(json.dumps(hapic.generate_doc(app)))
103
+print(json.dumps(hapic.generate_doc()))
99 104
 
100 105
 app.run(host='localhost', port=8080, debug=True)

+ 13 - 15
hapic/__init__.py View File

@@ -1,4 +1,5 @@
1 1
 # -*- coding: utf-8 -*-
2
+from hapic.context import BottleContext
2 3
 from hapic.hapic import Hapic
3 4
 
4 5
 _hapic_default = Hapic()
@@ -13,6 +14,7 @@ output_headers = _hapic_default.output_headers
13 14
 output_body = _hapic_default.output_body
14 15
 # with_api_doc_bis = _hapic_default.with_api_doc_bis
15 16
 generate_doc = _hapic_default.generate_doc
17
+set_context = _hapic_default.set_context
16 18
 handle_exception = _hapic_default.handle_exception
17 19
 
18 20
 # from hapic.hapic import with_api_doc
@@ -28,18 +30,14 @@ handle_exception = _hapic_default.handle_exception
28 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,3 +76,6 @@ class BottleContext(ContextInterface):
76 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,6 +61,7 @@ def bottle_generate_operations(
61 61
     # jsonschema based
62 62
     if description.input_path:
63 63
         schema_class = type(description.input_path.wrapper.processor.schema)
64
+        # TODO: look schema2parameters ?
64 65
         jsonschema = schema2jsonschema(schema_class, spec=spec)
65 66
         for name, schema in jsonschema.get('properties', {}).items():
66 67
             method_operations.setdefault('parameters', []).append({

+ 23 - 14
hapic/hapic.py View File

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