#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import logging
import requests
import certifi
from tencentcloud.common.http.pre_conn import PreConnAdapter
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
logger = logging.getLogger("tencentcloud_sdk_common")
def _get_proxy_from_env(host, varname="HTTPS_PROXY"):
no_proxy = os.environ.get("NO_PROXY") or os.environ.get("no_proxy")
if no_proxy and host in no_proxy:
return None
return os.environ.get(varname.lower()) or os.environ.get(varname.upper())
class ProxyConnection(object):
def __init__(self, host, timeout=60, proxy=None, certification=None, is_http=False, pre_conn_pool_size=0):
self.request_host = host
self.certification = certification
if certification is None:
self.certification = certifi.where()
self.timeout = timeout
self.proxy = None
if is_http:
proxy = proxy or _get_proxy_from_env(host, varname="HTTP_PROXY")
else:
proxy = proxy or _get_proxy_from_env(host, varname="HTTPS_PROXY")
if proxy:
self.proxy = {"http": proxy, "https": proxy}
self.request_length = 0
self._session = requests.Session()
if pre_conn_pool_size > 0:
adapter = PreConnAdapter(conn_pool_size=pre_conn_pool_size)
self._session.mount("https://", adapter)
self._session.mount("http://", adapter)
def request(self, method, url, body=None, headers=None):
headers.setdefault("Host", self.request_host)
return self._session.request(method=method,
url=url,
data=body,
headers=headers,
proxies=self.proxy,
verify=self.certification,
timeout=self.timeout,
stream=True)
class ApiRequest(object):
def __init__(self, host, req_timeout=60, debug=False, proxy=None, is_http=False, certification=None,
pre_conn_pool_size=0):
self.conn = ProxyConnection(host, timeout=req_timeout, proxy=proxy, certification=certification,
is_http=is_http, pre_conn_pool_size=pre_conn_pool_size)
self.is_http = is_http
self.host = host
self.req_timeout = req_timeout
self.keep_alive = False
self.debug = debug
self.request_size = 0
self.response_size = 0
def _handle_host(self, host):
url = urlparse(host)
if not url.hostname:
if self.is_http:
return "http://" + host
else:
return "https://" + host
return host
def set_req_timeout(self, req_timeout):
self.req_timeout = req_timeout
def is_keep_alive(self):
return self.keep_alive
def set_keep_alive(self, flag=True):
self.keep_alive = flag
def set_debug(self, debug):
self.debug = debug
def _request(self, req_inter):
url = self._handle_host(req_inter.host)
if self.keep_alive:
req_inter.header["Connection"] = "Keep-Alive"
logger.debug("SendRequest: %s" % req_inter)
if req_inter.method == 'GET':
req_inter_url = '%s?%s' % (url, req_inter.data)
return self.conn.request(req_inter.method, req_inter_url,
None, req_inter.header)
elif req_inter.method == 'POST':
return self.conn.request(req_inter.method, url,
req_inter.data, req_inter.header)
else:
raise TencentCloudSDKException(
"ClientParamsError", 'Method only support (GET, POST)')
def send_request(self, req_inter):
try:
http_resp = self._request(req_inter)
self.request_size = self.conn.request_length
return http_resp
except Exception as e:
raise TencentCloudSDKException("ClientNetworkError", str(e))
class RequestInternal(object):
def __init__(self, host="", method="", uri="", header=None, data=""):
if header is None:
header = {}
self.host = host
self.method = method
self.uri = uri
self.header = header
self.data = data
def __str__(self):
headers = "\n".join("%s: %s" % (k, v) for k, v in self.header.items())
return ("Host: %s\nMethod: %s\nUri: %s\nHeader: %s\nData: %s\n"
% (self.host, self.method, self.uri, headers, self.data))
class ResponsePrettyFormatter(object):
def __init__(self, resp, format_body=True, delimiter="\n"):
self._resp = resp
self._format_body = format_body
self._delimiter = delimiter
def __str__(self):
lines = ['%s %d %s' % (self.str_ver(self._resp.raw.version), self._resp.status_code, self._resp.reason)]
for k, v in self._resp.headers.items():
lines.append('%s: %s' % (k, v))
if self._format_body:
lines.append('')
lines.append(self._resp.text)
return self._delimiter.join(lines)
@staticmethod
def str_ver(ver):
if ver == 10:
return "HTTP/1.0"
elif ver == 11:
return "HTTP/1.1"
elif ver == 20:
return "HTTP/2.0"
else:
return str(ver)