add README.md to introduce the usage of tornado_swagger
[releng.git] / utils / test / result_collection_api / opnfv_testapi / tornado_swagger / README.md
1 # tornado-swagger
2
3 ## What is tornado-swagger?
4 tornado is a wrapper for tornado which enables swagger-ui support.
5
6 In essense, you just need to wrap the Api instance and add a few python decorators to
7 get full swagger support.http://swagger.io/
8
9
10 ## How to use:
11
12
13 ```python
14 from tornado.web import RequestHandler, HTTPError
15 from tornado_swagger import swagger
16
17 swagger.docs()
18
19 # You may decorate your operation with @swagger.operation and use docs to inform information
20 class ItemNoParamHandler(GenericApiHandler):
21     @swagger.operation(nickname='create')
22     def post(self):
23         """
24             @param body: create test results for a item.
25             @type body: L{Item}
26             @return 200: item is created.
27             @raise 400: invalid input
28         """
29
30 # Operations not decorated with @swagger.operation do not get added to the swagger docs
31
32 class ItemNoParamHandler(GenericApiHandler):
33     def options(self):
34         """
35         I'm not visible in the swagger docs
36         """
37         pass
38
39
40 # Then you use swagger.Application instead of tornado.web.Application
41 # and do other operations as usual
42
43 def make_app():
44     return swagger.Application([
45         (r"/items", ItemNoParamHandler),
46         (r"/items/([^/]+)", ItemHandler),
47         (r"/items/([^/]+)/cases/([^/]+)", ItemOptionParamHandler),
48     ])
49
50 # You define models like this:
51 @swagger.model
52 class Item:
53     """
54         @descriptin:
55             This is an example of a model class that has parameters in its constructor
56             and the fields in the swagger spec are derived from the parameters to __init__.
57         @notes:
58             In this case we would have property1, property2 as required parameters
59             and property3 as optional parameter.
60         @property property3: Item decription
61         @ptype property3: L{PropertySubclass}
62     """
63     def __init__(self, property1, property2=None):
64         self.property1 = property1
65         self.property2 = property2
66
67 # Swagger json:
68     "models": {
69         "Item": {
70             "description": "A description...",
71             "id": "Item",
72             "required": [
73                 "property1",
74             ],
75             "properties": [
76                 "property1": {
77                     "type": "string"
78                 },
79                 "property2": {
80                     "type": "string"
81                     "default": null
82                 }
83             ]
84         }
85     }
86
87 # If you declare an __init__ method with meaningful arguments
88 # then those args could be used to deduce the swagger model fields.
89 # just as shown above
90
91 # if you declare an @property in docs, this property property2 will also be used
92 # to deduce the swagger model fields
93 class Item:
94     """
95         @property property3: Item description
96     """
97     def __init__(self, property1, property2):
98         self.property1 = property1
99         self.property2 = property2
100
101 # Swagger json:
102     "models": {
103         "Item": {
104             "description": "A description...",
105             "id": "Item",
106             "required": [
107                 "property1",
108             ],
109             "properties": [
110                 "property1": {
111                     "type": "string"
112                 },
113                 "property2": {
114                     "type": "string"
115                 }
116                 "property3": {
117                     "type": "string"
118                 }
119             ]
120         }
121     }
122
123 # if you declare an argument with @ptype, the type of this argument will be specified
124 # rather than the default 'string'
125 class Item:
126     """
127         @ptype property3: L{PropertySubclass}
128     """
129     def __init__(self, property1, property2, property3=None):
130         self.property1 = property1
131         self.property2 = property2
132         self.property3 = property3
133
134 # Swagger json:
135     "models": {
136         "Item": {
137             "description": "A description...",
138             "id": "Item",
139             "required": [
140                 "property1",
141             ],
142             "properties": [
143                 "property1": {
144                     "type": "string"
145                 },
146                 "property2": {
147                     "type": "string"
148                 },
149                 "property3": {
150                     "type": "PropertySubclass"
151                     "default": null
152                 }
153             ]
154         }
155     }
156
157 # if you want to declare an list property, you can do it like this:
158 class Item:
159     """
160         @ptype property3: L{PropertySubclass}
161         @ptype property4: C{list} of L{PropertySubclass}
162     """
163     def __init__(self, property1, property2, property3, property4=None):
164         self.property1 = property1
165         self.property2 = property2
166         self.property3 = property3
167         self.property4 = property4
168
169 # Swagger json:
170     "models": {
171         "Item": {
172             "description": "A description...",
173             "id": "Item",
174             "required": [
175                 "property1",
176             ],
177             "properties": [
178                 "property1": {
179                     "type": "string"
180                 },
181                 "property2": {
182                     "type": "string"
183                 },
184                 "property3": {
185                     "type": "PropertySubclass"
186                     "default": null
187                 },
188                 "property4": {
189                     "default": null,
190                     "items": {
191                         "type": "PropertySubclass"},
192                         "type": "array"
193                     }
194                 }
195             ]
196         }
197     }
198
199 # if it is a query:
200 class ItemQueryHandler(GenericApiHandler):
201     @swagger.operation(nickname='query')
202     def get(self):
203         """
204            @param property1:
205            @type property1: L{string}
206            @in property1: query
207            @required property1: False
208
209            @param property2:
210            @type property2: L{string}
211            @in property2: query
212            @required property2: True
213            @rtype: L{Item}
214
215            @notes: GET /item?property1=1&property2=1
216         """
217
218 # Swagger json:
219     "apis": [
220         {
221             "operations": [
222                 {
223                     "parameters": [
224                         {
225                             "name": "property1",
226                             "dataType": "string",
227                             "paramType": "query",
228                             "description": ""
229                         },
230                         {
231                             "name": "property2",
232                             "dataType": "string",
233                             "paramType": "query",
234                             "required": true,
235                             "description": ""
236                         }
237                     ],
238                     "responseClass": "Item",
239                     "notes": null,
240                     "responseMessages": [],
241                     "summary": null,
242                     "httpMethod": "GET",
243                     "nickname": "query"
244                 }
245             ],
246             "path": "/item",
247             "description": null
248         },
249         ....
250     ]
251 ```
252
253 # Running and testing
254
255 Now run your tornado app
256
257 ```
258 python main.py
259 ```
260
261 And visit:
262
263 ```
264 curl http://ip:port/swagger/spec
265 ```
266
267 access to web
268 ```
269 http://ip:port/swagger/spec.html
270 ```
271
272 # Passing more metadata to swagger
273 customized arguments used in creating the 'swagger.docs' object will be supported later