suds с python 2.7, как предотвратить ssl.SSLError: ('Тайм-аут операции чтения',) - PullRequest
0 голосов
/ 08 октября 2018

У меня есть следующий код:

from suds.client import Client
from concurrent.futures import ThreadPoolExecutor, as_completed
from multiprocessing import cpu_count
from pandas import DataFrame
from sqlalchemy import create_engine

class Br:
def __init__(self, TOKEN, Br_WSDL):
    self.TOKEN = TOKEN
    self.Br_WSDL = Br_WSDL

def _get_bornto_data(self, page_num):
    self.bApi = Client(self.Br_WSDL)
    session_id = self.bApi.service.login(self.TOKEN)
    session_header = self.bApi.factory.create("sessionHeader")
    filter_type = self.bApi.factory.create("filterType")
    self.contact_filter = self.bApi.factory.create("contactFilter")
    session_header.sessionId = session_id
    self.bApi.set_options(soapheaders=session_header)
    self.contact_filter.listId.append(contacts_list_id)
    self.contact_filter.type = filter_type.AND
    return self.bApi.service.readContacts(self.contact_filter, False, [], page_num)

def get_Br_content(self, page_num):
    full_results = []
    for res in self._get_bornto_data(page_num):
        if "'" not in res["email"] and '"' not in res["email"]:
            full_results.append(dict(res))
    return full_results

NUM_WORKERS = cpu_count()
...
bro = Br(TOKEN=TOKEN, Br_WSDL=Br_WSDL)
while True:
    results = []
    pages = [i for i in range(c, c + NUM_WORKERS)]
    with ThreadPoolExecutor(NUM_WORKERS) as executor:
        futures = [executor.submit(bro.get_Br_content, page) for page in pages]
    for future in as_completed(futures):
        results.extend(future.result())
    if len(results) < 1:
        break
    print("Get batch {0} with {1} results".format(c, len(results)))
    df = DataFrame(results)
    df.to_sql(...)
    print("Pages {0} to {1} was insert".format(c, c + NUM_WORKERS))
    c += NUM_WORKERS

Этот код подключается к SOAP API, получает записи и вставляет их в базу данных MySQL.Этот код обычно работает нормально, но иногда терпит неудачу со временем ожидания:

Pages 184 to 188 was insert
Get batch 188 with 20000 results
Pages 188 to 192 was insert
Traceback (most recent call last):

...
    return self.bApi.service.readContacts(self.contact_filter, False, [], page_num)
  File "/usr/local/lib/python2.7/dist-packages/suds/client.py", line 521, in __call__
    return client.invoke(args, kwargs)
  ...
  File "/usr/lib/python2.7/httplib.py", line 453, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 409, in _read_status
    line = self.fp.readline(_MAXLINE + 1)
  File "/usr/lib/python2.7/socket.py", line 480, in readline
    data = self._sock.recv(self._rbufsize)
  File "/usr/lib/python2.7/ssl.py", line 756, in recv
    return self.read(buflen)
  File "/usr/lib/python2.7/ssl.py", line 643, in read
    v = self._sslobj.read(len)
ssl.SSLError: ('The read operation timed out',)

Как я могу избежать этого?Этот код скоро будет заменен другим скриптом, но до тех пор мне нужно, чтобы это работало.Есть ли способ перехватить исключения и повторить конкретную страницу, на которой возникла проблема, не выбрасывая весь процесс?

Я использую Python 2.7 (скоро мы перейдем на Python 3).

...