Source code for jdcloud_sdk.core.jdcloudclient

# coding=utf8

# Copyright 2018 JDCLOUD.COM
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import traceback
import requests
from jdcloud_sdk.core import const
from jdcloud_sdk.core.signer import Signer
from jdcloud_sdk.core.version import VERSION
from jdcloud_sdk.core.parameterbuilder import WithBodyBuilder, WithoutBodyBuilder
from jdcloud_sdk.core.exception import ClientException
from jdcloud_sdk.core.jdcloudresponse import JDCloudResponse, ErrorResponse
from jdcloud_sdk.core.logger import get_default_logger, INFO, ERROR
from jdcloud_sdk.core.util import base64encode, byte_to_str


[docs]class JDCloudClient(object): def __init__(self, credential, config, service_name, revision, logger): self.__config = config self.__service_name = service_name self.__credential = credential self.__revision = revision self.__logger = logger if logger is None: self.__logger = get_default_logger() self.__builder_map = {const.METHOD_GET: WithoutBodyBuilder, const.METHOD_DELETE: WithoutBodyBuilder, const.METHOD_HEAD: WithoutBodyBuilder, const.METHOD_PUT: WithBodyBuilder, const.METHOD_POST: WithBodyBuilder, const.METHOD_PATCH: WithBodyBuilder}
[docs] def send(self, request): if self.__config is None: raise ClientException('Miss config object') if self.__credential is None: raise ClientException('Miss credential object') if request is None: raise ClientException('Miss request object') if request.parameters is None: raise ClientException('Miss parameters in request') region = self.__get_region_id(request) try: header = self.__merge_headers(request.header) token = header.get(const.JDCLOUD_SECURITY_TOKEN, '') param_builder = self.__builder_map[request.method]() url = param_builder.build_url(request, self.__config.scheme, self.__config.endpoint) body = param_builder.build_body(request) self.__logger.log(INFO, 'url=' + url) self.__logger.log(INFO, 'body=' + body) signer = Signer(self.__logger) signer.sign(method=request.method, region=region, uri=url, headers=header, data=body, credential=self.__credential, security_token=token, service=self.__service_name) self.__logger.log(INFO, header) resp = requests.request(request.method, url, data=body, headers=header, timeout=self.__config.timeout) self.__logger.log(INFO, resp.content) return self.__process_response(request.method, resp) except Exception as expt: msg = traceback.format_exc() self.__logger.log(ERROR, msg) raise expt
def __merge_headers(self, request_header): headers = dict() headers['User-Agent'] = 'JdcloudSdkPython/%s %s/%s' % (VERSION, self.__service_name, self.__revision) headers['Content-Type'] = 'application/json' if request_header is not None and isinstance(request_header, dict): for key, value in request_header.items(): if key.lower() in const.HEADER_ERROR: raise ClientException('Please use header with prefix x-jdcloud') if key.lower() in const.HEADER_BASE64: value = base64encode(value) headers[key] = value self.__logger.log(INFO, headers) return headers def __get_region_id(self, request): if isinstance(request.parameters, dict): if 'regionId' in request.parameters and request.parameters['regionId'] is not None: return request.parameters['regionId'] else: if hasattr(request.parameters, 'regionId') and request.parameters.regionId is not None: return request.parameters.regionId return 'jdcloud-api' def __process_response(self, method, response): jd_resp = JDCloudResponse() content_length = response.headers.get(const.HEADER_CONTENT_LEN) if method == const.METHOD_HEAD or response.status_code in (204, 304) or content_length == '0': request_id = response.headers.get(const.HEADER_REQUESTID) if request_id is None or request_id == '': jd_resp.error = ErrorResponse('', response.status_code, 'can not get requestId in HEAD response') jd_resp.request_id = '' else: jd_resp.request_id = request_id else: jd_resp.fill_value(byte_to_str(response.content)) return jd_resp