aihc_handler.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # Copyright 2014 Baidu, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  4. # except in compliance with the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the
  9. # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  10. # either express or implied. See the License for the specific language governing permissions
  11. # and limitations under the License.
  12. """
  13. This module provides general http handler functions for processing http responses from AIHC V2 services.
  14. This module contains utility functions for parsing HTTP responses from AIHC (AI Hosting Cloud) services,
  15. including JSON parsing, error handling, and response object conversion. The functions are designed
  16. to work with the BCE (Baidu Cloud Engine) SDK framework.
  17. Functions:
  18. parse_json: Parse JSON response and convert to Python object
  19. dict_to_python_object: Convert dictionary to Python object with Expando
  20. parse_json_list: Parse JSON list response
  21. parse_error: Handle error responses and raise appropriate exceptions
  22. """
  23. import http.client
  24. import json
  25. from baidubce import compat, utils
  26. from baidubce.utils import Expando
  27. from baidubce.exception import BceClientError
  28. from baidubce.exception import BceServerError
  29. def parse_json(http_response, response):
  30. """
  31. Parse JSON response and convert to Python object.
  32. If the response body is not empty, convert it to a Python object and update
  33. the response object's attributes. The http_response is always closed if no error occurs.
  34. Args:
  35. http_response: The http_response object returned by HTTPConnection.getresponse()
  36. response: General response object which will be returned to the caller
  37. Returns:
  38. bool: Always returns True
  39. Note:
  40. This function removes the 'metadata' key from the response if it exists.
  41. """
  42. body = http_response.read()
  43. if body:
  44. response.__dict__.update(json.loads(
  45. body, object_hook=dict_to_python_object).__dict__)
  46. # 移除metadata key(如果存在)
  47. if 'metadata' in response.__dict__:
  48. del response.__dict__['metadata']
  49. http_response.close()
  50. return True
  51. def dict_to_python_object(d):
  52. """
  53. Convert dictionary to Python object with Expando.
  54. Args:
  55. d: Dictionary to convert
  56. Returns:
  57. Expando: Python object with dictionary attributes
  58. """
  59. attr = {}
  60. for k, v in list(d.items()):
  61. k = str(k)
  62. attr[k] = v
  63. return Expando(attr)
  64. def parse_json_list(http_response, response):
  65. """
  66. Parse JSON list response and convert to Python object.
  67. If the body is not empty, convert it to a Python object and set as the value of
  68. response.result. The http_response is always closed if no error occurs.
  69. Args:
  70. http_response: The http_response object returned by HTTPConnection.getresponse()
  71. response: General response object which will be returned to the caller
  72. Returns:
  73. bool: Always returns True
  74. """
  75. body = http_response.read()
  76. if body:
  77. body = compat.convert_to_string(body)
  78. response.__dict__["result"] = json.loads(body, object_hook=utils.dict_to_python_object)
  79. response.__dict__["raw_data"] = body
  80. http_response.close()
  81. return True
  82. def parse_error(http_response, response):
  83. """
  84. Handle error responses and raise appropriate exceptions.
  85. If the HTTP status code is not 2xx, parse the error response and raise
  86. appropriate BCE exceptions. The http_response is always closed.
  87. Args:
  88. http_response: The http_response object returned by HTTPConnection.getresponse()
  89. response: General response object which will be returned to the caller
  90. Returns:
  91. bool: False if HTTP status code is 2xx
  92. Raises:
  93. BceClientError: If HTTP status code is 1xx (not handled)
  94. BceServerError: If HTTP status code is not 2xx (error response)
  95. """
  96. if http_response.status // 100 == http.client.OK // 100:
  97. return False
  98. if http_response.status // 100 == http.client.CONTINUE // 100:
  99. raise BceClientError(b'Can not handle 1xx http status code')
  100. body = http_response.read()
  101. if not body:
  102. bse = BceServerError(http_response.reason, request_id=response.metadata.bce_request_id)
  103. bse.status_code = http_response.status
  104. raise bse
  105. error_dict = json.loads(compat.convert_to_string(body))
  106. message = str(error_dict)
  107. if 'message' in error_dict and error_dict['message'] is not None:
  108. message = error_dict['message']
  109. code = "Exception"
  110. if 'code' in error_dict and error_dict['code'] is not None:
  111. code = error_dict['code']
  112. request_id = response.metadata.bce_request_id
  113. if 'request_id' in error_dict and error_dict['request_id'] is not None:
  114. request_id = error_dict['request_id']
  115. bse = BceServerError(message, code=code, request_id=request_id)
  116. bse.status_code = http_response.status
  117. raise bse