cli.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # -*- coding:utf-8 -*-
  2. """
  3. DolphinScheduler API CLI 入口。
  4. 用法:
  5. python -m dw_base.ds.cli get <path> [-p k=v ...]
  6. python -m dw_base.ds.cli post <path> [-j '<json-body>' | -d k=v ...]
  7. python -m dw_base.ds.cli put <path> [-j '<json-body>' | -d k=v ...]
  8. 示例:
  9. python -m dw_base.ds.cli get /projects -p pageSize=10 -p pageNo=1
  10. python -m dw_base.ds.cli post /projects/123/workflow-definition -d name=wf -d desc=hi
  11. python -m dw_base.ds.cli put /projects/123/workflow-definition/100 -j '{"name":"wf"}'
  12. """
  13. import argparse
  14. import json
  15. import sys
  16. from dw_base.ds.api import DSClient
  17. def _parse_kv(items):
  18. d = {}
  19. for it in items or []:
  20. if '=' not in it:
  21. sys.stderr.write('参数 -p 需要 k=v 格式,跳过:' + it + '\n')
  22. continue
  23. k, v = it.split('=', 1)
  24. d[k] = v
  25. return d
  26. def main(argv=None):
  27. parser = argparse.ArgumentParser(prog='dw_base.ds.cli', description='DolphinScheduler API CLI')
  28. sub = parser.add_subparsers(dest='cmd')
  29. sub.required = True
  30. g = sub.add_parser('get', help='HTTP GET')
  31. g.add_argument('path', help='API path,如 /projects')
  32. g.add_argument('-p', action='append', default=[], metavar='k=v', help='query 参数(可多次)')
  33. g.add_argument('-o', dest='output', default=None, metavar='FILE', help='写 JSON 到文件(不打 stdout)')
  34. p = sub.add_parser('post', help='HTTP POST')
  35. p.add_argument('path')
  36. p.add_argument('-j', dest='body', default=None, metavar='JSON', help='JSON body(与 -d 互斥)')
  37. p.add_argument('-d', dest='form', action='append', default=[], metavar='k=v',
  38. help='form-data 参数(可多次,DS 3.x 多用 form-encoded;与 -j 互斥)')
  39. p.add_argument('-o', dest='output', default=None, metavar='FILE', help='写 JSON 到文件(不打 stdout)')
  40. u = sub.add_parser('put', help='HTTP PUT(如 workflow-definition 改造)')
  41. u.add_argument('path')
  42. u.add_argument('-j', dest='body', default=None, metavar='JSON', help='JSON body(与 -d 互斥)')
  43. u.add_argument('-d', dest='form', action='append', default=[], metavar='k=v',
  44. help='form-data 参数(可多次;与 -j 互斥)')
  45. u.add_argument('-o', dest='output', default=None, metavar='FILE', help='写 JSON 到文件(不打 stdout)')
  46. args = parser.parse_args(argv)
  47. client = DSClient()
  48. if args.cmd == 'get':
  49. result = client.get(args.path, params=_parse_kv(args.p))
  50. else:
  51. # post / put 共用 body / form 解析与互斥校验
  52. body = json.loads(args.body) if args.body else None
  53. form = _parse_kv(args.form) if args.form else None
  54. if body is not None and form is not None:
  55. sys.stderr.write('-j 与 -d 互斥\n')
  56. sys.exit(1)
  57. method = client.put if args.cmd == 'put' else client.post
  58. result = method(args.path, json_body=body, form_data=form)
  59. text = json.dumps(result, ensure_ascii=False, indent=2)
  60. if args.output:
  61. with open(args.output, 'w', encoding='utf-8') as f:
  62. f.write(text)
  63. f.write('\n')
  64. sys.stderr.write('[ds.cli] 已写到 {}\n'.format(args.output))
  65. else:
  66. print(text)
  67. if __name__ == '__main__':
  68. main()