diff --git a/README.rst b/README.rst index 982f603..b94ebb7 100644 --- a/README.rst +++ b/README.rst @@ -66,7 +66,7 @@ Usage CTRL-C to stop the continuous audio flow or use a timer #Move camera down - camera.ptz_control_command(action="start", code="Down", arg1=0, arg2=0, arg3=0))) + camera.ptz_control_command(action="start", code="Down", arg1=0, arg2=0, arg3=0) #Record realtime stream into a file camera.realtime_stream(path_file="/home/user/Desktop/myvideo") @@ -144,7 +144,7 @@ Supportability Matrix +-------------------------+---------------+----------+-----------------+ | IPM-HX1B | Yes | working | | +-------------------------+---------------+----------+-----------------+ -| IP3M-941 | Yes | working | | +| IP3M-941/941W | Yes | working | | +-------------------------+---------------+----------+-----------------+ | IP3M-HX2 | Yes (partial) | working | | +-------------------------+---------------+----------+-----------------+ diff --git a/configure.ac b/configure.ac index 80b8306..ff12176 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ # GNU General Public License for more details. define([VERSION_MAJOR], [1]) define([VERSION_MINOR], [2]) -define([VERSION_FIX], [3]) +define([VERSION_FIX], [4]) define([VERSION_NUMBER], VERSION_MAJOR[.]VERSION_MINOR[.]VERSION_FIX) define([VERSION_SUFFIX], [_master]) diff --git a/setup.py b/setup.py index 79257c7..f793e5e 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ def readme(): setup(name='amcrest', - version='1.2.3', + version='1.2.4', description='Python wrapper implementation for Amcrest cameras.', long_description=readme(), author='Douglas Schilling Landgraf, Marcelo Moreira de Mello', diff --git a/src/amcrest/http.py b/src/amcrest/http.py index 141c87e..b6bf7c5 100644 --- a/src/amcrest/http.py +++ b/src/amcrest/http.py @@ -12,8 +12,8 @@ # vim:sw=4:ts=4:et import logging import requests - from requests.adapters import HTTPAdapter +import threading from amcrest.utils import clean_url, pretty @@ -54,15 +54,12 @@ def __init__(self, host, port, user, self._protocol = protocol self._base_url = self.__base_url() - if timeout_protocol is None: - self._timeout_protocol = TIMEOUT_HTTP_PROTOCOL - else: - self._timeout_protocol = timeout_protocol + self._retries_default = (retries_connection or + MAX_RETRY_HTTP_CONNECTION) + self._timeout_default = timeout_protocol or TIMEOUT_HTTP_PROTOCOL - if retries_connection is None: - self._retries_conn = MAX_RETRY_HTTP_CONNECTION - else: - self._retries_conn = retries_connection + self._session = {} + self._get_session_lock = threading.Lock() self._token = self._generate_token() self._set_name() @@ -124,6 +121,18 @@ def __base_url(self, param=""): def get_base_url(self): return self._base_url + def _get_session(self, max_retries): + with self._get_session_lock: + try: + return self._session[max_retries] + except KeyError: + session = requests.Session() + adapter = HTTPAdapter(max_retries=max_retries) + session.mount('http://', adapter) + session.mount('https://', adapter) + self._session[max_retries] = session + return session + def command(self, cmd, retries=None, timeout_cmd=None): """ Args: @@ -131,42 +140,29 @@ def command(self, cmd, retries=None, timeout_cmd=None): timeout_cmd - timeout, default 3sec retries - maximum number of retries each connection should attempt """ - if timeout_cmd is not None: - self._timeout_protocol = timeout_cmd - - if retries is not None: - self._retries_conn = retries - - session = requests.Session() - session.mount('http://', HTTPAdapter(max_retries=self._retries_conn)) - session.mount('https://', HTTPAdapter(max_retries=self._retries_conn)) + retries = retries or self._retries_default + timeout = timeout_cmd or self._timeout_default + session = self._get_session(retries) url = self.__base_url(cmd) - resp = None - loop = 0 - while loop <= self._retries_conn: - loop += 1 + for loop in range(1, 2 + retries): _LOGGER.debug("Running query attempt %s", loop) try: resp = session.get( url, auth=self._token, stream=True, - timeout=self._timeout_protocol, + timeout=timeout, ) resp.raise_for_status() break except requests.HTTPError as error: - _LOGGER.debug("Trying again due error %s", error) - continue - - # keep the loop when 401 - if resp.status_code == 401: - continue - - # if we got here, let's raise because it did not work - if resp is None: - raise ValueError('Something went wrong!!!!') + if loop <= retries: + _LOGGER.warning("Trying again due to error %s", error) + continue + else: + _LOGGER.error("Query failed due to error %s", error) + raise _LOGGER.debug("Query worked. Exit code: <%s>", resp.status_code) return resp @@ -175,8 +171,7 @@ def command_audio(self, cmd, file_content, http_header, timeout=None): url = self.__base_url(cmd) - if timeout is not None: - timeout = self._timeout_protocol + timeout = timeout or self._timeout_default try: requests.post(