##// END OF EJS Templates
API cli should prefer to display errors instead of responses
marcink -
r3896:8dae2a28 beta
parent child Browse files
Show More
@@ -1,117 +1,121 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.bin.api
3 rhodecode.bin.api
4 ~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~
5
5
6 Api CLI client for RhodeCode
6 Api CLI client for RhodeCode
7
7
8 :created_on: Jun 3, 2012
8 :created_on: Jun 3, 2012
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 from __future__ import with_statement
26 from __future__ import with_statement
27 import sys
27 import sys
28 import argparse
28 import argparse
29
29
30 from rhodecode.bin.base import json, api_call, RcConf, FORMAT_JSON, FORMAT_PRETTY
30 from rhodecode.bin.base import json, api_call, RcConf, FORMAT_JSON, FORMAT_PRETTY
31
31
32
32
33 def argparser(argv):
33 def argparser(argv):
34 usage = (
34 usage = (
35 "rhodecode-api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
35 "rhodecode-api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
36 "[--config=CONFIG] [--save-config] "
36 "[--config=CONFIG] [--save-config] "
37 "METHOD <key:val> <key2:val> ...\n"
37 "METHOD <key:val> <key2:val> ...\n"
38 "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
38 "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
39 )
39 )
40
40
41 parser = argparse.ArgumentParser(description='RhodeCode API cli',
41 parser = argparse.ArgumentParser(description='RhodeCode API cli',
42 usage=usage)
42 usage=usage)
43
43
44 ## config
44 ## config
45 group = parser.add_argument_group('config')
45 group = parser.add_argument_group('config')
46 group.add_argument('--apikey', help='api access key')
46 group.add_argument('--apikey', help='api access key')
47 group.add_argument('--apihost', help='api host')
47 group.add_argument('--apihost', help='api host')
48 group.add_argument('--config', help='config file')
48 group.add_argument('--config', help='config file')
49 group.add_argument('--save-config', action='store_true', help='save the given config into a file')
49 group.add_argument('--save-config', action='store_true', help='save the given config into a file')
50
50
51 group = parser.add_argument_group('API')
51 group = parser.add_argument_group('API')
52 group.add_argument('method', metavar='METHOD', nargs='?', type=str, default=None,
52 group.add_argument('method', metavar='METHOD', nargs='?', type=str, default=None,
53 help='API method name to call followed by key:value attributes',
53 help='API method name to call followed by key:value attributes',
54 )
54 )
55 group.add_argument('--format', dest='format', type=str,
55 group.add_argument('--format', dest='format', type=str,
56 help='output format default: `%s` can '
56 help='output format default: `%s` can '
57 'be also `%s`' % (FORMAT_PRETTY, FORMAT_JSON),
57 'be also `%s`' % (FORMAT_PRETTY, FORMAT_JSON),
58 default=FORMAT_PRETTY
58 default=FORMAT_PRETTY
59 )
59 )
60 args, other = parser.parse_known_args()
60 args, other = parser.parse_known_args()
61 return parser, args, other
61 return parser, args, other
62
62
63
63
64 def main(argv=None):
64 def main(argv=None):
65 """
65 """
66 Main execution function for cli
66 Main execution function for cli
67
67
68 :param argv:
68 :param argv:
69 """
69 """
70 if argv is None:
70 if argv is None:
71 argv = sys.argv
71 argv = sys.argv
72
72
73 conf = None
73 conf = None
74 parser, args, other = argparser(argv)
74 parser, args, other = argparser(argv)
75
75
76 api_credentials_given = (args.apikey and args.apihost)
76 api_credentials_given = (args.apikey and args.apihost)
77 if args.save_config:
77 if args.save_config:
78 if not api_credentials_given:
78 if not api_credentials_given:
79 raise parser.error('--save-config requires --apikey and --apihost')
79 raise parser.error('--save-config requires --apikey and --apihost')
80 conf = RcConf(config_location=args.config,
80 conf = RcConf(config_location=args.config,
81 autocreate=True, config={'apikey': args.apikey,
81 autocreate=True, config={'apikey': args.apikey,
82 'apihost': args.apihost})
82 'apihost': args.apihost})
83 sys.exit()
83 sys.exit()
84
84
85 if not conf:
85 if not conf:
86 conf = RcConf(config_location=args.config, autoload=True)
86 conf = RcConf(config_location=args.config, autoload=True)
87 if not conf:
87 if not conf:
88 if not api_credentials_given:
88 if not api_credentials_given:
89 parser.error('Could not find config file and missing '
89 parser.error('Could not find config file and missing '
90 '--apikey or --apihost in params')
90 '--apikey or --apihost in params')
91
91
92 apikey = args.apikey or conf['apikey']
92 apikey = args.apikey or conf['apikey']
93 apihost = args.apihost or conf['apihost']
93 apihost = args.apihost or conf['apihost']
94 method = args.method
94 method = args.method
95
95
96 # if we don't have method here it's an error
96 # if we don't have method here it's an error
97 if not method:
97 if not method:
98 parser.error('Please specify method name')
98 parser.error('Please specify method name')
99
99
100 try:
100 try:
101 margs = dict(map(lambda s: s.split(':', 1), other))
101 margs = dict(map(lambda s: s.split(':', 1), other))
102 except Exception:
102 except Exception:
103 sys.stderr.write('Error parsing arguments \n')
103 sys.stderr.write('Error parsing arguments \n')
104 sys.exit()
104 sys.exit()
105 if args.format == FORMAT_PRETTY:
105 if args.format == FORMAT_PRETTY:
106 print 'Calling method %s => %s' % (method, apihost)
106 print 'Calling method %s => %s' % (method, apihost)
107
107
108 json_data = api_call(apikey, apihost, method, **margs)['result']
108 json_resp = api_call(apikey, apihost, method, **margs)
109 if json_resp['error']:
110 json_data = json_resp['error']
111 else:
112 json_data = json_resp['result']
109 if args.format == FORMAT_JSON:
113 if args.format == FORMAT_JSON:
110 print json.dumps(json_data)
114 print json.dumps(json_data)
111 elif args.format == FORMAT_PRETTY:
115 elif args.format == FORMAT_PRETTY:
112 print 'Server response \n%s' % (
116 print 'Server response \n%s' % (
113 json.dumps(json_data, indent=4, sort_keys=True))
117 json.dumps(json_data, indent=4, sort_keys=True))
114 return 0
118 return 0
115
119
116 if __name__ == '__main__':
120 if __name__ == '__main__':
117 sys.exit(main(sys.argv))
121 sys.exit(main(sys.argv))
General Comments 0
You need to be logged in to leave comments. Login now