-
Notifications
You must be signed in to change notification settings - Fork 2
/
cinp-codegen
executable file
·184 lines (139 loc) · 5.42 KB
/
cinp-codegen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/usr/bin/env python3
import sys
import os
import logging
import urllib
from datetime import datetime
from optparse import OptionParser
from cinp import client
oparser = OptionParser( description='CInP Auto Documentation', usage='usage %prog [options] <CInP endpoint, ie: http://service/api/v1/ >' )
oparser.add_option( '-s', '--service', help='Service name' )
oparser.add_option( '-p', '--proxy', help='HTTP Proxy', default=None )
oparser.add_option( '-d', '--dir', help='Target Directory, default: "gen"', metavar='DIRNAME', default='gen' )
oparser.add_option( '-l', '--language', help='Target Language, note: rst is reStructuredText for documentation, default: rst', default='rst', choices=[ 'rst', 'python', 'go', 'ts', 'rust' ] )
oparser.add_option( '-v', '--verbose', default=False, action='store_true' )
def get_namespace( cinp, url ):
try:
item, type = cinp.describe( url )
except client.NotAuthorized:
logging.warning( 'Describing Namespace "{0}" is not Authorized'.format( url ) )
return
if type != 'Namespace':
logging.error( 'Expected Namespace got "{0}"'.format( type ) )
return
result = {
'name': item[ 'name' ],
'url': url,
'doc': item.get( 'doc', '' ).strip(),
'api_version': item[ 'api-version' ],
'model_list': [],
'namespace_list': []
}
for url in item[ 'models' ]:
model = get_model( cinp, url )
if model is not None:
result[ 'model_list' ].append( model )
for url in item[ 'namespaces' ]:
namespace = get_namespace( cinp, url )
if namespace is not None:
result[ 'namespace_list' ].append( namespace )
return result
def get_model( cinp, url ):
try:
item, type = cinp.describe( url )
except client.NotAuthorized:
logging.warning( 'Describing Model "{0}" is not Authorized'.format( url ) )
return
if type != 'Model':
logging.error( 'Expected Model got "{0}"'.format( type ) )
return
result = {
'name': item[ 'name' ],
'url': url,
'doc': item.get( 'doc', '' ).strip(),
'constant_map': item[ 'constants' ],
'list_filter_map': item[ 'list-filters' ],
'field_list': item[ 'fields' ],
'not_allowed_verb_list': item[ 'not-allowed-verbs' ],
'query_filter_fields': item[ 'query-filter-fields' ],
'query_sort_fields': item[ 'query-sort-fields' ],
'id_field_name': item.get( 'id-field-name', None ),
'action_list': []
}
for url in item[ 'actions' ]:
tmp = get_action( cinp, url )
if tmp is not None:
result[ 'action_list' ].append( tmp )
return result
def get_action( cinp, url ):
try:
item, type = cinp.describe( url )
except client.NotAuthorized:
logging.warning( 'Describing Action "{0}" is not Authorized'.format( url ) )
return None
if type != 'Action':
logging.error( 'Expected Action got "{0}"'.format( type ) )
return None
return_type = item.get( 'return-type', None )
if return_type is not None and return_type[ 'type' ] is None:
return_type = None
return( {
'name': item[ 'name' ],
'url': url,
'static': item[ 'static' ],
'return_type': return_type,
'paramater_list': item.get( 'paramaters', [] )
} )
def main():
( options, args ) = oparser.parse_args()
if len( args ) != 1:
oparser.error( 'CInP Enpoint required' )
if not options.service: # TODO: also regex service name to make sure it is valid
oparser.error( 'Service name is required' )
elif options.language == 'rst':
from cinp_utils.codegen_rst import rst_render_func
render_func = rst_render_func
elif options.language == 'python':
from cinp_utils.codegen_python import python_render_func
render_func = python_render_func
elif options.language == 'go':
from cinp_utils.codegen_go import go_render_func
render_func = go_render_func
elif options.language == 'ts':
from cinp_utils.codegen_ts import ts_render_func
render_func = ts_render_func
elif options.language == 'rust':
from cinp_utils.codegen_rust import rust_render_func
render_func = rust_render_func
else:
oparser.error( 'Unknown Language Type "{0}"'.format( options.language ) )
sys.exit( 1 )
try:
url = urllib.parse.urlparse( args[0] )
except ValueError:
oparser.error( 'Error Parsing "{0}"'.format( args[0] ) )
sys.exit( 1 )
wrk_dir = options.dir
if not os.path.isdir( wrk_dir ):
oparser.error( 'Target Dir is does not exist or is not a Directory "{0}"'.format( wrk_dir ) )
sys.exit( 1 )
logging.basicConfig()
handler = logging.StreamHandler( sys.stderr )
if options.verbose:
handler.setLevel( logging.DEBUG )
else:
handler.setLevel( logging.INFO )
try:
cinp = client.CInP( '{0}://{1}:{2}'.format( url.scheme, url.hostname, url.port if url.port is not None else 80 ), url.path, options.proxy )
header_map = { 'url': args[0], 'service': options.service, 'root_path': url.path, 'timestamp': datetime.utcnow().isoformat() }
root = get_namespace( cinp, url.path )
if root is None:
logging.error( 'Unable to Describe root node' )
sys.exit( 1 )
render_func( wrk_dir, header_map, root )
except Exception as e:
logging.exception( 'Error "{0}", Aborting.'.format( e ) )
sys.exit( 1 )
sys.exit( 0 )
if __name__ == '__main__':
main()