sc-oa 0.7.0.13__py3-none-any.whl → 0.7.0.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sc-oa might be problematic. Click here for more details.
- {sc_oa-0.7.0.13.dist-info → sc_oa-0.7.0.14.dist-info}/LICENSE +23 -23
- {sc_oa-0.7.0.13.dist-info → sc_oa-0.7.0.14.dist-info}/METADATA +45 -42
- sc_oa-0.7.0.14.dist-info/RECORD +26 -0
- {sc_oa-0.7.0.13.dist-info → sc_oa-0.7.0.14.dist-info}/WHEEL +1 -1
- sphinxcontrib/__init__.py +10 -0
- sphinxcontrib/openapi/__init__.py +93 -93
- sphinxcontrib/openapi/__main__.py +86 -86
- sphinxcontrib/openapi/_lib2to3.py +378 -378
- sphinxcontrib/openapi/directive.py +58 -58
- sphinxcontrib/openapi/locale/es_ES/LC_MESSAGES/openapi.po +170 -170
- sphinxcontrib/openapi/locale/fr_FR/LC_MESSAGES/openapi.po +170 -170
- sphinxcontrib/openapi/locale/openapi.pot +168 -168
- sphinxcontrib/openapi/openapi20.py +263 -263
- sphinxcontrib/openapi/openapi30.py +748 -748
- sphinxcontrib/openapi/renderers/__init__.py +18 -18
- sphinxcontrib/openapi/renderers/_description.py +26 -26
- sphinxcontrib/openapi/renderers/_httpdomain.py +620 -620
- sphinxcontrib/openapi/renderers/_httpdomain_old.py +59 -59
- sphinxcontrib/openapi/renderers/_model.py +422 -422
- sphinxcontrib/openapi/renderers/_toc.py +48 -48
- sphinxcontrib/openapi/renderers/abc.py +46 -46
- sphinxcontrib/openapi/schema_utils.py +137 -137
- sphinxcontrib/openapi/utils.py +137 -137
- sc_oa-0.7.0.13-py3.9-nspkg.pth +0 -1
- sc_oa-0.7.0.13.dist-info/RECORD +0 -27
- sc_oa-0.7.0.13.dist-info/namespace_packages.txt +0 -1
- {sc_oa-0.7.0.13.dist-info → sc_oa-0.7.0.14.dist-info}/top_level.txt +0 -0
|
@@ -1,263 +1,263 @@
|
|
|
1
|
-
"""
|
|
2
|
-
sphinxcontrib.openapi.openapi20
|
|
3
|
-
-------------------------------
|
|
4
|
-
|
|
5
|
-
The OpenAPI 2.0 (f.k.a. Swagger) spec renderer. Based on
|
|
6
|
-
``sphinxcontrib-httpdomain``.
|
|
7
|
-
|
|
8
|
-
:copyright: (c) 2016, Ihor Kalnytskyi.
|
|
9
|
-
:license: BSD, see LICENSE for details.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import collections
|
|
13
|
-
import itertools
|
|
14
|
-
import re
|
|
15
|
-
|
|
16
|
-
from sphinxcontrib.openapi import utils
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _httpresource(endpoint, method, properties, convert):
|
|
20
|
-
parameters = properties.get('parameters', [])
|
|
21
|
-
responses = properties['responses']
|
|
22
|
-
indent = ' '
|
|
23
|
-
|
|
24
|
-
yield '.. http:{0}:: {1}'.format(method, endpoint)
|
|
25
|
-
yield ' :synopsis: {0}'.format(properties.get('summary', 'null'))
|
|
26
|
-
yield ''
|
|
27
|
-
|
|
28
|
-
if 'summary' in properties:
|
|
29
|
-
for line in properties['summary'].splitlines():
|
|
30
|
-
yield '{indent}**{line}**'.format(**locals())
|
|
31
|
-
yield ''
|
|
32
|
-
|
|
33
|
-
if 'description' in properties:
|
|
34
|
-
for line in convert(properties['description']).splitlines():
|
|
35
|
-
yield '{indent}{line}'.format(**locals())
|
|
36
|
-
yield ''
|
|
37
|
-
|
|
38
|
-
for param in filter(lambda p: p['in'] == 'path', parameters):
|
|
39
|
-
yield indent + ':param {type} {name}:'.format(**param)
|
|
40
|
-
for line in convert(param.get('description', '')).splitlines():
|
|
41
|
-
yield '{indent}{indent}{line}'.format(**locals())
|
|
42
|
-
|
|
43
|
-
# print request's query params
|
|
44
|
-
for param in filter(lambda p: p['in'] == 'query', parameters):
|
|
45
|
-
yield indent + ':query {type} {name}:'.format(**param)
|
|
46
|
-
for line in convert(param.get('description', '')).splitlines():
|
|
47
|
-
yield '{indent}{indent}{line}'.format(**locals())
|
|
48
|
-
|
|
49
|
-
# print the json body params
|
|
50
|
-
for param in filter(lambda p: p['in'] == 'body', parameters):
|
|
51
|
-
if 'schema' in param:
|
|
52
|
-
yield ''
|
|
53
|
-
for line in convert_json_schema(param['schema']):
|
|
54
|
-
yield '{indent}{line}'.format(**locals())
|
|
55
|
-
yield ''
|
|
56
|
-
|
|
57
|
-
# print response status codes
|
|
58
|
-
for status, response in sorted(responses.items()):
|
|
59
|
-
yield '{indent}:status {status}:'.format(**locals())
|
|
60
|
-
for line in convert(response['description']).splitlines():
|
|
61
|
-
yield '{indent}{indent}{line}'.format(**locals())
|
|
62
|
-
|
|
63
|
-
# print request header params
|
|
64
|
-
for param in filter(lambda p: p['in'] == 'header', parameters):
|
|
65
|
-
yield indent + ':reqheader {name}:'.format(**param)
|
|
66
|
-
for line in convert(param.get('description', '')).splitlines():
|
|
67
|
-
yield '{indent}{indent}{line}'.format(**locals())
|
|
68
|
-
|
|
69
|
-
# print response headers
|
|
70
|
-
for status, response in responses.items():
|
|
71
|
-
for headername, header in response.get('headers', {}).items():
|
|
72
|
-
yield indent + ':resheader {name}:'.format(name=headername)
|
|
73
|
-
for line in convert(header['description']).splitlines():
|
|
74
|
-
yield '{indent}{indent}{line}'.format(**locals())
|
|
75
|
-
|
|
76
|
-
for status, response in responses.items():
|
|
77
|
-
if not is_2xx_response(status):
|
|
78
|
-
continue
|
|
79
|
-
if 'schema' in response:
|
|
80
|
-
yield ''
|
|
81
|
-
for line in convert_json_schema(
|
|
82
|
-
response['schema'], directive=':>json'):
|
|
83
|
-
yield '{indent}{line}'.format(**locals())
|
|
84
|
-
yield ''
|
|
85
|
-
|
|
86
|
-
yield ''
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def convert_json_schema(schema, directive=':<json'):
|
|
90
|
-
"""
|
|
91
|
-
Convert json schema to `:<json` sphinx httpdomain.
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
output = []
|
|
95
|
-
|
|
96
|
-
def _convert(schema, name='', required=False):
|
|
97
|
-
"""
|
|
98
|
-
Fill the output list, with 2-tuple (name, template)
|
|
99
|
-
|
|
100
|
-
i.e: ('user.age', 'str user.age: the age of user')
|
|
101
|
-
|
|
102
|
-
This allow to sort output by field name
|
|
103
|
-
"""
|
|
104
|
-
|
|
105
|
-
type_ = schema.get('type', 'any')
|
|
106
|
-
required_properties = schema.get('required', ())
|
|
107
|
-
if type_ == 'object' and schema.get('properties'):
|
|
108
|
-
for prop, next_schema in schema.get('properties', {}).items():
|
|
109
|
-
_convert(
|
|
110
|
-
next_schema, '{name}.{prop}'.format(**locals()),
|
|
111
|
-
(prop in required_properties))
|
|
112
|
-
|
|
113
|
-
elif type_ == 'array':
|
|
114
|
-
_convert(schema['items'], name + '[]')
|
|
115
|
-
|
|
116
|
-
else:
|
|
117
|
-
if name:
|
|
118
|
-
name = name.lstrip('.')
|
|
119
|
-
constraints = []
|
|
120
|
-
if required:
|
|
121
|
-
constraints.append('required')
|
|
122
|
-
if schema.get('readOnly', False):
|
|
123
|
-
constraints.append('read only')
|
|
124
|
-
if constraints:
|
|
125
|
-
constraints = '({})'.format(', '.join(constraints))
|
|
126
|
-
else:
|
|
127
|
-
constraints = ''
|
|
128
|
-
|
|
129
|
-
if schema.get('description', ''):
|
|
130
|
-
if constraints:
|
|
131
|
-
output.append((
|
|
132
|
-
name,
|
|
133
|
-
'{type_} {name}:'
|
|
134
|
-
' {schema[description]}'
|
|
135
|
-
' {constraints}'.format(**locals())))
|
|
136
|
-
else:
|
|
137
|
-
output.append((
|
|
138
|
-
name,
|
|
139
|
-
'{type_} {name}:'
|
|
140
|
-
' {schema[description]}'.format(**locals())))
|
|
141
|
-
|
|
142
|
-
else:
|
|
143
|
-
if constraints:
|
|
144
|
-
output.append(
|
|
145
|
-
(name,
|
|
146
|
-
'{type_} {name}:'
|
|
147
|
-
' {constraints}'.format(**locals())))
|
|
148
|
-
else:
|
|
149
|
-
output.append(
|
|
150
|
-
(name,
|
|
151
|
-
'{type_} {name}:'.format(**locals())))
|
|
152
|
-
|
|
153
|
-
_convert(schema)
|
|
154
|
-
|
|
155
|
-
for _, render in sorted(output):
|
|
156
|
-
yield '{} {}'.format(directive, render)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def is_2xx_response(status):
|
|
160
|
-
try:
|
|
161
|
-
status = int(status)
|
|
162
|
-
return 200 <= status < 300
|
|
163
|
-
except ValueError:
|
|
164
|
-
pass
|
|
165
|
-
return False
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def _header(title):
|
|
169
|
-
yield title
|
|
170
|
-
yield '=' * len(title)
|
|
171
|
-
yield ''
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def openapihttpdomain(spec, **options):
|
|
175
|
-
if 'examples' in options:
|
|
176
|
-
raise ValueError(
|
|
177
|
-
'Rendering examples is not supported for OpenAPI v2.x specs.')
|
|
178
|
-
|
|
179
|
-
if 'request' in options:
|
|
180
|
-
raise ValueError(
|
|
181
|
-
'The :request: option is not supported for OpenAPI v2.x specs.')
|
|
182
|
-
|
|
183
|
-
generators = []
|
|
184
|
-
|
|
185
|
-
# OpenAPI spec may contain JSON references, common properties, etc.
|
|
186
|
-
# Trying to render the spec "As Is" will require to put multiple
|
|
187
|
-
# if-s around the code. In order to simplify flow, let's make the
|
|
188
|
-
# spec to have only one (expected) schema, i.e. normalize it.
|
|
189
|
-
utils.normalize_spec(spec, **options)
|
|
190
|
-
|
|
191
|
-
# Paths list to be processed
|
|
192
|
-
paths = []
|
|
193
|
-
|
|
194
|
-
# If 'paths' are passed we've got to ensure they exist within an OpenAPI
|
|
195
|
-
# spec; otherwise raise error and ask user to fix that.
|
|
196
|
-
if 'paths' in options:
|
|
197
|
-
if not set(options['paths']).issubset(spec['paths']):
|
|
198
|
-
raise ValueError(
|
|
199
|
-
'One or more paths are not defined in the spec: %s.' % (
|
|
200
|
-
', '.join(set(options['paths']) - set(spec['paths'])),
|
|
201
|
-
)
|
|
202
|
-
)
|
|
203
|
-
paths = options['paths']
|
|
204
|
-
|
|
205
|
-
# Check against regular expressions to be included
|
|
206
|
-
if 'include' in options:
|
|
207
|
-
for i in options['include']:
|
|
208
|
-
ir = re.compile(i)
|
|
209
|
-
for path in spec['paths']:
|
|
210
|
-
if ir.match(path):
|
|
211
|
-
paths.append(path)
|
|
212
|
-
|
|
213
|
-
# If no include nor paths option, then take full path
|
|
214
|
-
if 'include' not in options and 'paths' not in options:
|
|
215
|
-
paths = spec['paths']
|
|
216
|
-
|
|
217
|
-
# Remove paths matching regexp
|
|
218
|
-
if 'exclude' in options:
|
|
219
|
-
_paths = []
|
|
220
|
-
for e in options['exclude']:
|
|
221
|
-
er = re.compile(e)
|
|
222
|
-
for path in paths:
|
|
223
|
-
if not er.match(path):
|
|
224
|
-
_paths.append(path)
|
|
225
|
-
paths = _paths
|
|
226
|
-
|
|
227
|
-
if 'group' in options:
|
|
228
|
-
groups = collections.OrderedDict(
|
|
229
|
-
[(x['name'], []) for x in spec.get('tags', {})]
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
for endpoint in paths:
|
|
233
|
-
for method, properties in spec['paths'][endpoint].items():
|
|
234
|
-
if options.get('methods') and method not in options.get('methods'):
|
|
235
|
-
continue
|
|
236
|
-
key = properties.get('tags', [''])[0]
|
|
237
|
-
groups.setdefault(key, []).append(_httpresource(
|
|
238
|
-
endpoint,
|
|
239
|
-
method,
|
|
240
|
-
properties,
|
|
241
|
-
utils.get_text_converter(options),
|
|
242
|
-
))
|
|
243
|
-
|
|
244
|
-
for key in groups.keys():
|
|
245
|
-
if key:
|
|
246
|
-
generators.append(_header(key))
|
|
247
|
-
else:
|
|
248
|
-
generators.append(_header('default'))
|
|
249
|
-
|
|
250
|
-
generators.extend(groups[key])
|
|
251
|
-
else:
|
|
252
|
-
for endpoint in paths:
|
|
253
|
-
for method, properties in spec['paths'][endpoint].items():
|
|
254
|
-
if options.get('methods') and method not in options.get('methods'):
|
|
255
|
-
continue
|
|
256
|
-
generators.append(_httpresource(
|
|
257
|
-
endpoint,
|
|
258
|
-
method,
|
|
259
|
-
properties,
|
|
260
|
-
utils.get_text_converter(options),
|
|
261
|
-
))
|
|
262
|
-
|
|
263
|
-
return iter(itertools.chain(*generators))
|
|
1
|
+
"""
|
|
2
|
+
sphinxcontrib.openapi.openapi20
|
|
3
|
+
-------------------------------
|
|
4
|
+
|
|
5
|
+
The OpenAPI 2.0 (f.k.a. Swagger) spec renderer. Based on
|
|
6
|
+
``sphinxcontrib-httpdomain``.
|
|
7
|
+
|
|
8
|
+
:copyright: (c) 2016, Ihor Kalnytskyi.
|
|
9
|
+
:license: BSD, see LICENSE for details.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import collections
|
|
13
|
+
import itertools
|
|
14
|
+
import re
|
|
15
|
+
|
|
16
|
+
from sphinxcontrib.openapi import utils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _httpresource(endpoint, method, properties, convert):
|
|
20
|
+
parameters = properties.get('parameters', [])
|
|
21
|
+
responses = properties['responses']
|
|
22
|
+
indent = ' '
|
|
23
|
+
|
|
24
|
+
yield '.. http:{0}:: {1}'.format(method, endpoint)
|
|
25
|
+
yield ' :synopsis: {0}'.format(properties.get('summary', 'null'))
|
|
26
|
+
yield ''
|
|
27
|
+
|
|
28
|
+
if 'summary' in properties:
|
|
29
|
+
for line in properties['summary'].splitlines():
|
|
30
|
+
yield '{indent}**{line}**'.format(**locals())
|
|
31
|
+
yield ''
|
|
32
|
+
|
|
33
|
+
if 'description' in properties:
|
|
34
|
+
for line in convert(properties['description']).splitlines():
|
|
35
|
+
yield '{indent}{line}'.format(**locals())
|
|
36
|
+
yield ''
|
|
37
|
+
|
|
38
|
+
for param in filter(lambda p: p['in'] == 'path', parameters):
|
|
39
|
+
yield indent + ':param {type} {name}:'.format(**param)
|
|
40
|
+
for line in convert(param.get('description', '')).splitlines():
|
|
41
|
+
yield '{indent}{indent}{line}'.format(**locals())
|
|
42
|
+
|
|
43
|
+
# print request's query params
|
|
44
|
+
for param in filter(lambda p: p['in'] == 'query', parameters):
|
|
45
|
+
yield indent + ':query {type} {name}:'.format(**param)
|
|
46
|
+
for line in convert(param.get('description', '')).splitlines():
|
|
47
|
+
yield '{indent}{indent}{line}'.format(**locals())
|
|
48
|
+
|
|
49
|
+
# print the json body params
|
|
50
|
+
for param in filter(lambda p: p['in'] == 'body', parameters):
|
|
51
|
+
if 'schema' in param:
|
|
52
|
+
yield ''
|
|
53
|
+
for line in convert_json_schema(param['schema']):
|
|
54
|
+
yield '{indent}{line}'.format(**locals())
|
|
55
|
+
yield ''
|
|
56
|
+
|
|
57
|
+
# print response status codes
|
|
58
|
+
for status, response in sorted(responses.items()):
|
|
59
|
+
yield '{indent}:status {status}:'.format(**locals())
|
|
60
|
+
for line in convert(response['description']).splitlines():
|
|
61
|
+
yield '{indent}{indent}{line}'.format(**locals())
|
|
62
|
+
|
|
63
|
+
# print request header params
|
|
64
|
+
for param in filter(lambda p: p['in'] == 'header', parameters):
|
|
65
|
+
yield indent + ':reqheader {name}:'.format(**param)
|
|
66
|
+
for line in convert(param.get('description', '')).splitlines():
|
|
67
|
+
yield '{indent}{indent}{line}'.format(**locals())
|
|
68
|
+
|
|
69
|
+
# print response headers
|
|
70
|
+
for status, response in responses.items():
|
|
71
|
+
for headername, header in response.get('headers', {}).items():
|
|
72
|
+
yield indent + ':resheader {name}:'.format(name=headername)
|
|
73
|
+
for line in convert(header['description']).splitlines():
|
|
74
|
+
yield '{indent}{indent}{line}'.format(**locals())
|
|
75
|
+
|
|
76
|
+
for status, response in responses.items():
|
|
77
|
+
if not is_2xx_response(status):
|
|
78
|
+
continue
|
|
79
|
+
if 'schema' in response:
|
|
80
|
+
yield ''
|
|
81
|
+
for line in convert_json_schema(
|
|
82
|
+
response['schema'], directive=':>json'):
|
|
83
|
+
yield '{indent}{line}'.format(**locals())
|
|
84
|
+
yield ''
|
|
85
|
+
|
|
86
|
+
yield ''
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def convert_json_schema(schema, directive=':<json'):
|
|
90
|
+
"""
|
|
91
|
+
Convert json schema to `:<json` sphinx httpdomain.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
output = []
|
|
95
|
+
|
|
96
|
+
def _convert(schema, name='', required=False):
|
|
97
|
+
"""
|
|
98
|
+
Fill the output list, with 2-tuple (name, template)
|
|
99
|
+
|
|
100
|
+
i.e: ('user.age', 'str user.age: the age of user')
|
|
101
|
+
|
|
102
|
+
This allow to sort output by field name
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
type_ = schema.get('type', 'any')
|
|
106
|
+
required_properties = schema.get('required', ())
|
|
107
|
+
if type_ == 'object' and schema.get('properties'):
|
|
108
|
+
for prop, next_schema in schema.get('properties', {}).items():
|
|
109
|
+
_convert(
|
|
110
|
+
next_schema, '{name}.{prop}'.format(**locals()),
|
|
111
|
+
(prop in required_properties))
|
|
112
|
+
|
|
113
|
+
elif type_ == 'array':
|
|
114
|
+
_convert(schema['items'], name + '[]')
|
|
115
|
+
|
|
116
|
+
else:
|
|
117
|
+
if name:
|
|
118
|
+
name = name.lstrip('.')
|
|
119
|
+
constraints = []
|
|
120
|
+
if required:
|
|
121
|
+
constraints.append('required')
|
|
122
|
+
if schema.get('readOnly', False):
|
|
123
|
+
constraints.append('read only')
|
|
124
|
+
if constraints:
|
|
125
|
+
constraints = '({})'.format(', '.join(constraints))
|
|
126
|
+
else:
|
|
127
|
+
constraints = ''
|
|
128
|
+
|
|
129
|
+
if schema.get('description', ''):
|
|
130
|
+
if constraints:
|
|
131
|
+
output.append((
|
|
132
|
+
name,
|
|
133
|
+
'{type_} {name}:'
|
|
134
|
+
' {schema[description]}'
|
|
135
|
+
' {constraints}'.format(**locals())))
|
|
136
|
+
else:
|
|
137
|
+
output.append((
|
|
138
|
+
name,
|
|
139
|
+
'{type_} {name}:'
|
|
140
|
+
' {schema[description]}'.format(**locals())))
|
|
141
|
+
|
|
142
|
+
else:
|
|
143
|
+
if constraints:
|
|
144
|
+
output.append(
|
|
145
|
+
(name,
|
|
146
|
+
'{type_} {name}:'
|
|
147
|
+
' {constraints}'.format(**locals())))
|
|
148
|
+
else:
|
|
149
|
+
output.append(
|
|
150
|
+
(name,
|
|
151
|
+
'{type_} {name}:'.format(**locals())))
|
|
152
|
+
|
|
153
|
+
_convert(schema)
|
|
154
|
+
|
|
155
|
+
for _, render in sorted(output):
|
|
156
|
+
yield '{} {}'.format(directive, render)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def is_2xx_response(status):
|
|
160
|
+
try:
|
|
161
|
+
status = int(status)
|
|
162
|
+
return 200 <= status < 300
|
|
163
|
+
except ValueError:
|
|
164
|
+
pass
|
|
165
|
+
return False
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _header(title):
|
|
169
|
+
yield title
|
|
170
|
+
yield '=' * len(title)
|
|
171
|
+
yield ''
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def openapihttpdomain(spec, **options):
|
|
175
|
+
if 'examples' in options:
|
|
176
|
+
raise ValueError(
|
|
177
|
+
'Rendering examples is not supported for OpenAPI v2.x specs.')
|
|
178
|
+
|
|
179
|
+
if 'request' in options:
|
|
180
|
+
raise ValueError(
|
|
181
|
+
'The :request: option is not supported for OpenAPI v2.x specs.')
|
|
182
|
+
|
|
183
|
+
generators = []
|
|
184
|
+
|
|
185
|
+
# OpenAPI spec may contain JSON references, common properties, etc.
|
|
186
|
+
# Trying to render the spec "As Is" will require to put multiple
|
|
187
|
+
# if-s around the code. In order to simplify flow, let's make the
|
|
188
|
+
# spec to have only one (expected) schema, i.e. normalize it.
|
|
189
|
+
utils.normalize_spec(spec, **options)
|
|
190
|
+
|
|
191
|
+
# Paths list to be processed
|
|
192
|
+
paths = []
|
|
193
|
+
|
|
194
|
+
# If 'paths' are passed we've got to ensure they exist within an OpenAPI
|
|
195
|
+
# spec; otherwise raise error and ask user to fix that.
|
|
196
|
+
if 'paths' in options:
|
|
197
|
+
if not set(options['paths']).issubset(spec['paths']):
|
|
198
|
+
raise ValueError(
|
|
199
|
+
'One or more paths are not defined in the spec: %s.' % (
|
|
200
|
+
', '.join(set(options['paths']) - set(spec['paths'])),
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
paths = options['paths']
|
|
204
|
+
|
|
205
|
+
# Check against regular expressions to be included
|
|
206
|
+
if 'include' in options:
|
|
207
|
+
for i in options['include']:
|
|
208
|
+
ir = re.compile(i)
|
|
209
|
+
for path in spec['paths']:
|
|
210
|
+
if ir.match(path):
|
|
211
|
+
paths.append(path)
|
|
212
|
+
|
|
213
|
+
# If no include nor paths option, then take full path
|
|
214
|
+
if 'include' not in options and 'paths' not in options:
|
|
215
|
+
paths = spec['paths']
|
|
216
|
+
|
|
217
|
+
# Remove paths matching regexp
|
|
218
|
+
if 'exclude' in options:
|
|
219
|
+
_paths = []
|
|
220
|
+
for e in options['exclude']:
|
|
221
|
+
er = re.compile(e)
|
|
222
|
+
for path in paths:
|
|
223
|
+
if not er.match(path):
|
|
224
|
+
_paths.append(path)
|
|
225
|
+
paths = _paths
|
|
226
|
+
|
|
227
|
+
if 'group' in options:
|
|
228
|
+
groups = collections.OrderedDict(
|
|
229
|
+
[(x['name'], []) for x in spec.get('tags', {})]
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
for endpoint in paths:
|
|
233
|
+
for method, properties in spec['paths'][endpoint].items():
|
|
234
|
+
if options.get('methods') and method not in options.get('methods'):
|
|
235
|
+
continue
|
|
236
|
+
key = properties.get('tags', [''])[0]
|
|
237
|
+
groups.setdefault(key, []).append(_httpresource(
|
|
238
|
+
endpoint,
|
|
239
|
+
method,
|
|
240
|
+
properties,
|
|
241
|
+
utils.get_text_converter(options),
|
|
242
|
+
))
|
|
243
|
+
|
|
244
|
+
for key in groups.keys():
|
|
245
|
+
if key:
|
|
246
|
+
generators.append(_header(key))
|
|
247
|
+
else:
|
|
248
|
+
generators.append(_header('default'))
|
|
249
|
+
|
|
250
|
+
generators.extend(groups[key])
|
|
251
|
+
else:
|
|
252
|
+
for endpoint in paths:
|
|
253
|
+
for method, properties in spec['paths'][endpoint].items():
|
|
254
|
+
if options.get('methods') and method not in options.get('methods'):
|
|
255
|
+
continue
|
|
256
|
+
generators.append(_httpresource(
|
|
257
|
+
endpoint,
|
|
258
|
+
method,
|
|
259
|
+
properties,
|
|
260
|
+
utils.get_text_converter(options),
|
|
261
|
+
))
|
|
262
|
+
|
|
263
|
+
return iter(itertools.chain(*generators))
|