13
13
# limitations under the License.
14
14
15
15
import json
16
+ import operator
16
17
import os .path
17
18
import sys
18
19
from collections import OrderedDict
19
20
21
+
22
+ # these four constants are shown as part of this example in []:
23
+ # "[watch]Pod[List]" is the deprecated version of "[list]Pod?[watch]=True"
24
+ WATCH_OP_PREFIX = "watch"
25
+ WATCH_OP_SUFFIX = "List"
26
+ LIST_OP_PREFIX = "list"
27
+ WATCH_QUERY_PARAM_NAME = "watch"
28
+
29
+
20
30
_ops = ['get' , 'put' , 'post' , 'delete' , 'options' , 'head' , 'patch' ]
21
31
22
32
33
+ class PreprocessingException (Exception ):
34
+ pass
35
+
36
+
23
37
def _title (s ):
24
38
if len (s ) == 0 :
25
39
return s
@@ -30,24 +44,72 @@ def _to_camel_case(s):
30
44
return '' .join (_title (y ) for y in s .split ("_" ))
31
45
32
46
33
- def iterate_through_operations (spec , func ):
47
+ def apply_func_to_spec_operations (spec , func , * params ):
48
+ """Apply func to each operation in the spec.
49
+
50
+ :param spec: The OpenAPI spec to apply func to.
51
+ :param func: the function to apply to the spec's operations. It should be
52
+ a func(operation, parent) where operation will be each
53
+ operation of the spec and parent would be the parent object of
54
+ the given operation.
55
+ If the return value of the func is True, then the operation
56
+ will be deleted from the spec.
57
+ """
34
58
for k , v in spec ['paths' ].iteritems ():
35
59
for op in _ops :
36
- if op in v :
37
- func (v [op ])
60
+ if op not in v :
61
+ continue
62
+ if func (v [op ], v , * params ):
63
+ del v [op ]
64
+
65
+
66
+ def _has_property (prop_list , property_name ):
67
+ for prop in prop_list :
68
+ if prop ["name" ] == property_name :
69
+ return True
70
+
71
+
72
+ def remove_watch_operations (op , parent , operation_ids ):
73
+ op_id = op ['operationId' ]
74
+ if not op_id .startswith (WATCH_OP_PREFIX ):
75
+ return
76
+ list_id = (LIST_OP_PREFIX +
77
+ op_id .replace (WATCH_OP_SUFFIX , "" )[len (WATCH_OP_PREFIX ):])
78
+ if list_id not in operation_ids :
79
+ raise PreprocessingException ("Cannot find %s" % list_id )
80
+ list_op = operation_ids [list_id ]
81
+ params = []
82
+ if 'parameters' in list_op :
83
+ params += list_op ['parameters' ]
84
+ if 'parameters' in parent :
85
+ params += parent ['parameters' ]
86
+ if not _has_property (params , WATCH_QUERY_PARAM_NAME ):
87
+ raise PreprocessingException ("%s has no watch query param" % list_id )
88
+ return True
89
+
90
+
91
+ def strip_tags_from_operation_id (operation , _ ):
92
+ operation_id = operation ['operationId' ]
93
+ for t in operation ['tags' ]:
94
+ operation_id = operation_id .replace (_to_camel_case (t ), '' )
95
+ operation ['operationId' ] = operation_id
38
96
39
97
40
98
def process_swagger (infile , outfile ):
41
99
with open (infile , 'r' ) as f :
42
100
spec = json .load (f , object_pairs_hook = OrderedDict )
43
101
44
- def strip_tags_from_operation_id ( operation ):
45
- operation_id = operation [ 'operationId' ]
46
- for t in operation [ 'tags' ]:
47
- operation_id = operation_id . replace ( _to_camel_case ( t ), '' )
48
- operation ['operationId' ] = operation_id
102
+ apply_func_to_spec_operations ( spec , strip_tags_from_operation_id )
103
+
104
+ operation_ids = {}
105
+ apply_func_to_spec_operations ( spec , lambda op , _ : operator . setitem (
106
+ operation_ids , op ['operationId' ], op ))
49
107
50
- iterate_through_operations (spec , strip_tags_from_operation_id )
108
+ try :
109
+ apply_func_to_spec_operations (
110
+ spec , remove_watch_operations , operation_ids )
111
+ except PreprocessingException as e :
112
+ print (e .message )
51
113
52
114
with open (outfile , 'w' ) as out :
53
115
json .dump (spec , out , sort_keys = False , indent = 2 ,
0 commit comments