api.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. from starlette.formparsers import MultiPartParser as StartletteMultiPartParser
  2. from fastapi import APIRouter, Request, Response, Depends
  3. from fastapi.responses import FileResponse
  4. from key import v1 as key_v1
  5. from hub import methods, Global
  6. import importlib
  7. router = APIRouter()
  8. config_dict = {
  9. 'v5': {
  10. # --- 关于渣包车 ---
  11. 2001: 'v5.hs2000.code_2001', # 获取全部渣包车状态接口
  12. 2002: 'v5.hs2000.code_2002', # 指定渣包车点火操作接口
  13. 2003: 'v5.hs2000.code_2003', # 指定渣包车熄火操作接口
  14. 2004: 'v5.hs2000.code_2004', # 指定渣包车建立远程操作权限(或是切换)接口
  15. # 2005: 'v5.hs2000.code_2005', # 创建并执行自动驾驶任务【已停用】
  16. 2101: 'v5.hs2000.code_2101', # 新增渣包车接口
  17. 2102: 'v5.hs2000.code_2102', # 修改渣包车接口
  18. 2103: 'v5.hs2000.code_2103', # 删除渣包车接口
  19. # --- 关于关于任务 ---
  20. 3001: 'v5.hs3000.code_3001', # 任务列表数据获取接口(分页)
  21. # 3002: 'v5.hs3000.code_3002', # 任务暂停接口【已停用】
  22. 3003: 'v5.hs3000.code_3003', # 任务取消消接口
  23. 3004: 'v5.hs3000.code_3004', # 任务创建并执行接口
  24. 3005: 'v5.hs3000.code_3005', # 获取指定任务信息
  25. # --- 关于场地数据 ---
  26. 4001: 'v5.hs4000.code_4001', # 获取全部渣包状态数据接口
  27. # 4002: 'v5.hs4000.code_4002', # todo 获取接渣口状态数据
  28. # 4003: 'v5.hs4000.code_4003', # todo 获取倒渣口状态数据
  29. # --- 关于告警 ---
  30. 5001: 'v5.hs5000.code_5001', # 获取告警数据列表接口
  31. }
  32. }
  33. methods_dict = {} # {<tag>: {<method>: <path>}}
  34. def _get_method_by_code(code, tag):
  35. """
  36. 通过code获取method(不调用不加载)
  37. """
  38. try:
  39. # --- check ---
  40. if tag not in methods_dict:
  41. methods_dict[tag] = {}
  42. # --- check ---
  43. if code in methods_dict.get(tag):
  44. return methods_dict.get(tag).get(code)
  45. # --- get method ---
  46. method_path = config_dict.get(tag).get(code)
  47. tag, file_name, method_name = method_path.split('.')
  48. script = importlib.import_module(f"api.{tag}.{file_name}")
  49. method = getattr(script, method_name)
  50. # --- set method ---
  51. methods_dict[tag][code] = method
  52. return method
  53. except Exception as exception:
  54. methods.debug_log('api._get_method_by_code.69', f"#exception: {exception.__class__.__name__}")
  55. methods.debug_log('api._get_method_by_code.69', f"#traceback: {methods.trace_log()}")
  56. @router.post('/{tag}/api')
  57. async def post(tag: str, request: Request, response: Response, user: dict = Depends(key_v1.login_required)):
  58. """"""
  59. # --- check ---
  60. if not user.get('skip_is'):
  61. response.headers['authorization'] = key_v1.get_token_by_user(user)
  62. # --- get sources ---
  63. sources = await request.json()
  64. # tag = sources.get('tag')
  65. code = int(sources.get('code'))
  66. page = sources.get('page', 1)
  67. size = sources.get('size', 10)
  68. ban_keys = ['code']
  69. # --- set global args ---
  70. sources = {key: val for key, val in sources.items() if key not in ban_keys}
  71. sources['g_user_id'] = user.get('uid')
  72. sources['g_user_name'] = user.get('username')
  73. sources['g_user_pass'] = user.get('password')
  74. sources['g_role_id'] = user.get('role_id')
  75. # --- call action ---
  76. try:
  77. run_at = methods.now_ts()
  78. method = _get_method_by_code(code=code, tag=tag)
  79. result = await method(**sources)
  80. methods.debug_log(f"api.post.101", f"#{tag}/{code}: use time {round(methods.now_ts() - run_at, 2)}s")
  81. # --- check ---
  82. if code in [
  83. # 8201, # 访客记录,列表
  84. ] and result.__class__.__name__ == 'dict':
  85. return dict(
  86. code=result.get('code'),
  87. data=result.get('data', [])[(page - 1) * size: page * size],
  88. page=page,
  89. size=size,
  90. total=len(result.get('data', [])),
  91. )
  92. elif result.__class__.__name__ in ['FileResponse', 'dict']:
  93. return result
  94. else:
  95. return dict(data=result, type=result.__class__.__name__)
  96. except Exception as exception:
  97. methods.debug_log('api.post.121', f"#tag: {tag}, #code: {code}")
  98. methods.debug_log('api.post.121', f"#exception: {exception.__class__.__name__}")
  99. methods.debug_log('api.post.121', f"#traceback: {methods.trace_log()}")
  100. return dict(code=-1, data=[],
  101. reason=f"{exception.__class__.__name__}",
  102. detail=f"{methods.trace_log()}")
  103. @router.put('/actions')
  104. async def upload(request: Request, user: dict = Depends(key_v1.login_required)):
  105. try:
  106. # --- get sources ---
  107. sources = dict()
  108. parser = StartletteMultiPartParser(request.headers, request.stream())
  109. params = await parser.parse()
  110. # sources['params'] = params
  111. # --- set sources --- fromdata列表处理
  112. for key, value in params.multi_items():
  113. # --- check list ---
  114. if key[-4:] == 'list' and key not in sources:
  115. sources[key] = list()
  116. if key[-4:] == 'list':
  117. sources[key].append(value)
  118. # --- make list ---
  119. else:
  120. if key in sources:
  121. sources[key] = [sources[key]]
  122. sources[key].append(value)
  123. else:
  124. sources[key] = value
  125. # --- clean ---
  126. tag = sources.get('tag', 'v1')
  127. code = int(sources.get('code'))
  128. del sources['tag']
  129. del sources['code']
  130. # --- set sources ---
  131. sources['g_user_id'] = user.get('uid')
  132. sources['g_user_name'] = user.get('username')
  133. sources['g_user_pass'] = user.get('password')
  134. sources['g_role_id'] = user.get('role_id')
  135. # --- set files ---
  136. files = dict()
  137. for key, value in sources.items():
  138. if value.__class__.__name__ == 'UploadFile':
  139. files[key] = value
  140. for key, value in files.items():
  141. del sources[key]
  142. sources['files'] = files
  143. # --- call action ---
  144. return await _get_method_by_code(code=code, tag=tag)(**sources)
  145. except Exception as exception:
  146. methods.debug_log('api.upload', f"m-299: exception | {exception.__class__.__name__}")
  147. methods.debug_log('api.upload', f"m-299: traceback | {methods.trace_log()}")
  148. return dict(code=-1,
  149. reason=f"{exception.__class__.__name__}",
  150. detail=f"{methods.trace_log()}")
  151. @router.get('/api')
  152. async def download(request: Request, response: Response, user: dict = Depends(key_v1.login_required)):
  153. try:
  154. parser = StartletteMultiPartParser(request.headers, request.stream())
  155. params = await parser.parse()
  156. instance_id = params.get('instance_id')
  157. report = Global.mdb.get_one_by_id('', instance_id)
  158. report_path = report.get('report') if report else ''
  159. if not report_path:
  160. return ''
  161. return FileResponse(report_path)
  162. except Exception as exception:
  163. methods.debug_log('api.download.201', f"#exception: {exception.__class__.__name__}")
  164. methods.debug_log('api.download.201', f"#traceback: {methods.trace_log()}")
  165. return dict(code=-1,
  166. reason=f"{exception.__class__.__name__}",
  167. detail=f"{methods.trace_log()}")