From 6e5ae0a4ac26b65a7498cd2cb40e2fb413321f49 Mon Sep 17 00:00:00 2001 From: Eduard Carrerars Date: Fri, 8 Oct 2021 14:48:54 +0200 Subject: [PATCH] Add timeout --- cnmc_client/client.py | 40 ++++++++++++++++++++++------------------ cnmc_client/cnmc.py | 26 ++++++++------------------ 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/cnmc_client/client.py b/cnmc_client/client.py index 3bf3674..3099fb4 100644 --- a/cnmc_client/client.py +++ b/cnmc_client/client.py @@ -10,8 +10,9 @@ AVAILABLE_FILE_STATES = ["DISPONIBLE", "DESCARGADO"] CUPS_CHUNK_SIZE = 10 + class Client(object): - def __init__(self, key=None, secret=None, environment=None): + def __init__(self, key=None, secret=None, environment=None, timeout=None): # Handle the key self.key = key @@ -29,10 +30,9 @@ def __init__(self, key=None, secret=None, environment=None): self.environment = "prod" if environment: self.environment = environment - + self.timeout = timeout self.API = CNMC_API(key=self.key, secret=self.secret, environment=self.environment) - def test(self, message): """ Test do not follow the default method @@ -40,7 +40,10 @@ def test(self, message): params = { "m": message, } - response = self.API.get(resource="/test/v1/echoseguro", params=params) + response = self.API.get( + resource="/test/v1/echoseguro", params=params, + timeout=self.timeout + ) # Validate and deserialize the response schema = TestSchema() @@ -51,7 +54,6 @@ def test(self, message): else: raise ValueError('Result deserialization is not performed properly for "{}"'.format(repr(result))) - def list(self, status=None, date_start=None, date_end=None): """ List downloaded files or files able to be downloaded, with the capacity of filter it by: @@ -82,7 +84,10 @@ def list(self, status=None, date_start=None, date_end=None): params['fechaHasta'] = date_start # Ask the API - response = self.API.post(resource="/ficheros/v1/consultar", params=params) + response = self.API.post( + resource="/ficheros/v1/consultar", params=params, + timeout=self.timeout + ) # Validate and deserialize the response schema = ListSchema() @@ -93,7 +98,6 @@ def list(self, status=None, date_start=None, date_end=None): else: raise ValueError('Result deserialization is not performed properly for "{}"'.format(repr(result))) - def fetch_massive(self, cups, file_type, as_csv=False, wait=0): """ Fetch massively a list of CUPS, internally will chunk it to ask N fetch requests @@ -101,6 +105,7 @@ def fetch_massive(self, cups, file_type, as_csv=False, wait=0): :param cups: list of cups to fetch :param file_type: desired files to download, see available SIPS files :param as_csv: bool flag to return a CSV or a BytesIO instance + :param wait: number of seconds to wait before the next reaquest chunk :return: List of CNMC_File models //{'code': 200, 'result': , 'error': False} """ results = [] @@ -109,16 +114,12 @@ def fetch_massive(self, cups, file_type, as_csv=False, wait=0): for chunk_block in chunk_indexes: time.sleep(wait) - - cups_block = cups[chunk_block : chunk_block+CUPS_CHUNK_SIZE] - + cups_block = cups[chunk_block:chunk_block+CUPS_CHUNK_SIZE] result = self.fetch(cups_block, file_type, as_csv) - results.append(result) return results - def fetch(self, cups, file_type, as_csv=False): """ Fetch partial data for a list of CUPS @@ -148,7 +149,11 @@ def fetch(self, cups, file_type, as_csv=False): } # Ask the API - response = self.API.download(resource="/verticales/v1/SIPS/consulta/v1/{}.csv".format(file_type), params=params) + response = self.API.download( + resource="/verticales/v1/SIPS/consulta/v1/{}.csv".format(file_type), + params=params, + timeout=self.timeout + ) # Return a csv reader if needed if as_csv: @@ -165,10 +170,6 @@ def fetch(self, cups, file_type, as_csv=False): else: raise ValueError('Fetch result deserialization is not performed properly for "{}"'.format(repr(result))) - - return response - - def download(self, filename): """ Download @@ -181,5 +182,8 @@ def download(self, filename): assert type(filename) == str # Ask the API - response = self.API.get(resource="/ficheros/v1/descarga/{}".format(filename)) + response = self.API.get( + resource="/ficheros/v1/descarga/{}".format(filename), + timeout=self.timeout + ) return response diff --git a/cnmc_client/cnmc.py b/cnmc_client/cnmc.py index 1a9ea7f..896518a 100644 --- a/cnmc_client/cnmc.py +++ b/cnmc_client/cnmc.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import socket import httplib import oauth.oauth as oauth import urllib @@ -13,6 +14,7 @@ } NULL_TOKEN = None + class CNMC_API(object): def __init__(self, key=None, secret=None, environment=None, **kwargs): @@ -42,10 +44,6 @@ def __init__(self, key=None, secret=None, environment=None, **kwargs): self.url = CNCM_envs[self.environment] - self.NIF = self.get_NIF() - - - def get_NIF(self): """ Get NIF from test API method @@ -55,17 +53,9 @@ def get_NIF(self): response = self.get(resource="/test/v1/nif") assert response['code'] == 200, "Connection is not established properly '{}'. Review oauth configuraion".format(str(response)) - assert 'result' in response and 'empresa' in response['result'] and response['result']['empresa'][0] + assert 'result' in response and 'empresa' in response['result'] and response['result']['empresa'][0] return response['result']['empresa'][0] - - def set_request_token (self): - """ - Set the request token for current session - """ - self.request_token = self.session.fetch_request_token(self.url) - - def method(self, method, resource, download=False, **kwargs): """ Main method handler @@ -76,7 +66,7 @@ def method(self, method, resource, download=False, **kwargs): from urlparse import urlparse parsed = urlparse(url) params = kwargs.get('params', None) - #response = self.session.request(method=method, url=url, **kwargs) + timeout = kwargs.get('timeout', socket._GLOBAL_DEFAULT_TIMEOUT) consumer = oauth.OAuthConsumer(self.key, self.secret) signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1() oauth_request = oauth.OAuthRequest.from_consumer_and_token( @@ -84,7 +74,10 @@ def method(self, method, resource, download=False, **kwargs): parameters=params ) oauth_request.sign_request(signature_method_hmac_sha1, consumer, NULL_TOKEN) - connection = httplib.HTTPSConnection("%s:%d" % (parsed.hostname, parsed.port or 443)) + connection = httplib.HTTPSConnection( + "%s:%d" % (parsed.hostname, parsed.port or 443), + timeout=timeout + ) if method == 'GET' and params: resource +='?{}'.format( urllib.urlencode(params) @@ -113,21 +106,18 @@ def method(self, method, resource, download=False, **kwargs): 'error': False, } - def get(self, resource, **kwargs): """ GET method, it dispatch a session.get method consuming the desired resource """ return self.method(method="GET", resource=resource, **kwargs) - def post(self, resource, **kwargs): """ POST method, it dispatch a session.get method consuming the desired resource """ return self.method(method="POST", resource=resource, **kwargs) - def download(self, resource, **kwargs): """ GET method, it dispatch a session.get method consuming the desired resource