diff --git a/deepomatic/api/http_helper.py b/deepomatic/api/http_helper.py index 710f20a..48f31bf 100644 --- a/deepomatic/api/http_helper.py +++ b/deepomatic/api/http_helper.py @@ -209,15 +209,41 @@ def recursive_json_dump(prefix, obj, data_dict, omit_dot=False): return new_dict def send_request(self, requests_callable, *args, **kwargs): - # requests_callable must be a method from the requests module - # this is the timeout of requests module requests_timeout = kwargs.pop('timeout', self.requests_timeout) + + files = kwargs.pop('files', None) + if files: + for key, f in files.items(): + # file can be a tuple + # if so, the fileobj is in second position + if isinstance(f, (tuple, list)): + f = f[1] + if f is None or isinstance(f, (string_types, bytes, bytearray, int, float, bool)): + continue + error = "Unsupported file object type '{}' for key '{}'".format(type(f), key) + # seek files before each retry, to avoid silently retrying with different input + if hasattr(f, 'seek'): + if hasattr(f, 'seekable') and not f.seekable(): + raise DeepomaticException("{}: not seekable".format(error)) + f.seek(0) + continue + + raise DeepomaticException("{}: not a scalar or seekable.".format(error)) + + return requests_callable(*args, files=files, + timeout=requests_timeout, + verify=self.verify_ssl, + **kwargs) + + def maybe_retry_send_request(self, requests_callable, *args, **kwargs): + # requests_callable must be a method from the requests module + http_retry = kwargs.pop('http_retry', self.http_retry) - functor = functools.partial(requests_callable, *args, - verify=self.verify_ssl, - timeout=requests_timeout, **kwargs) + functor = functools.partial(self.send_request, + requests_callable, + *args, **kwargs) if http_retry is not None: return http_retry.retry(functor) @@ -274,10 +300,10 @@ def make_request(self, func, resource, params=None, data=None, if not resource.startswith('http'): resource = self.resource_prefix + resource - response = self.send_request(func, resource, *args, - params=params, data=data, - files=files, headers=headers, - stream=stream, **kwargs) + response = self.maybe_retry_send_request(func, resource, *args, + params=params, data=data, + files=files, headers=headers, + stream=stream, **kwargs) # Close opened files for file in opened_files: diff --git a/deepomatic/api/version.py b/deepomatic/api/version.py index f4f3cf1..a7fa864 100644 --- a/deepomatic/api/version.py +++ b/deepomatic/api/version.py @@ -1,6 +1,6 @@ __title__ = 'deepomatic-api' __description__ = 'Deepomatic API client' -__version__ = '0.9.2' +__version__ = '0.9.3' __author__ = 'deepomatic' __author_email__ = 'support@deepomatic.com' __url__ = 'https://github.com/deepomatic/deepomatic-client-python' diff --git a/demo.py b/demo.py index 6847e0f..1f7013a 100644 --- a/demo.py +++ b/demo.py @@ -359,7 +359,7 @@ def download_file(url): filename = os.path.join(tempfile.gettempdir(), hashlib.sha1(url.encode()).hexdigest() + ext) if os.path.exists(filename): # avoid redownloading - logger.info("Skipping download of {}: file already exist in ".format(url, filename)) + logger.info("Skipping download of {}: file already exist in {}".format(url, filename)) return filename r = requests.get(url, stream=True) r.raise_for_status() diff --git a/requirements.dev.txt b/requirements.dev.txt index 6a2542d..a579324 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -3,3 +3,4 @@ pytest==4.6.5 pytest-cov==2.7.1 pytest-voluptuous==1.1.0 httpretty==0.9.6 +flake8==3.8.4 diff --git a/requirements.txt b/requirements.txt index 01fca15..9e16833 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,3 @@ promise>=2.1,<3 six>=1.10.0,<2 requests>=2.19.0,<3 # will not work below in python3 tenacity>=5.1,<6 -flake8>=3.7,<4 diff --git a/setup.py b/setup.py index 58addf5..f0d6af7 100644 --- a/setup.py +++ b/setup.py @@ -2,17 +2,9 @@ import io from setuptools import find_packages, setup -try: - # for pip >= 10 - from pip._internal.req import parse_requirements -except ImportError: - # for pip <= 9.0.3 - from pip.req import parse_requirements - here = os.path.abspath(os.path.dirname(__file__)) - about = {} with io.open(os.path.join(here, 'deepomatic', 'api', 'version.py'), 'r', encoding='utf-8') as f: exec(f.read(), about) @@ -24,7 +16,8 @@ os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) # Read requirements -install_reqs = parse_requirements(os.path.join(here, 'requirements.txt'), session='hack') +with io.open(os.path.join(here, 'requirements.txt'), encoding='utf-8') as f: + requirements = f.readlines() namespaces = ['deepomatic'] @@ -43,7 +36,7 @@ long_description=README, long_description_content_type='text/markdown', data_files=[('', ['requirements.txt'])], - install_requires=[str(ir.req) for ir in install_reqs], + install_requires=requirements, python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", classifiers=[ 'Operating System :: OS Independent',