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