8000 Allow configuring SOAP request timeout · AmarisAI/python-stdnum@5fd1ae0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5fd1ae0

Browse files
committed
Allow configuring SOAP request timeout
This adds a timeout parameter to all checks that use a SOAP web service to reduce the blocking time. The default timeout for all checks is 30 seconds.
1 parent c113613 commit 5fd1ae0

File tree

5 files changed

+47
-35
lines changed

5 files changed

+47
-35
lines changed

stdnum/do/ncf.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ncf.py - functions for handling Dominican Republic invoice numbers
22
# coding: utf-8
33
#
4-
# Copyright (C) 2017 Arthur de Jong
4+
# Copyright (C) 2018 Arthur de Jong
55
#
66
# This library is free software; you can redistribute it and/or
77
# modify it under the terms of the GNU Lesser General Public
@@ -99,12 +99,13 @@ def _convert_result(result): # pragma: no cover
9999
for key, value in json.loads(result.replace('\t', '\\t')).items())
100100

101101

102-
def check_dgii(rnc, ncf): # pragma: no cover
102+
def check_dgii(rnc, ncf, timeout=30): # pragma: no cover
103103
"""Validate the RNC, NCF combination on using the DGII online web service.
104104
105105
This uses the validation service run by the the Dirección General de
106106
Impuestos Internos, the Dominican Republic tax department to check
107-
whether the combination of RNC and NCF is valid.
107+
whether the combination of RNC and NCF is valid. The timeout is in
108+
seconds.
108109
109110
Returns a dict with the following structure::
110111
@@ -122,7 +123,7 @@ def check_dgii(rnc, ncf): # pragma: no cover
122123
from stdnum.do.rnc import dgii_wsdl
123124
rnc = rnc_compact(rnc)
124125
ncf = compact(ncf)
125-
client = get_soap_client(dgii_wsdl)
126+
client = get_soap_client(dgii_wsdl, timeout)
126127
result = client.GetNCF(
127128
RNC=rnc,
128129
NCF=ncf,

stdnum/do/rnc.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# rnc.py - functions for handling Dominican Republic tax registration
22
# coding: utf-8
33
#
4-
# Copyright (C) 2015-2017 Arthur de Jong
4+
# Copyright (C) 2015-2018 Arthur de Jong
55
#
66
# This library is free software; you can redistribute it and/or
77
# modify it under the terms of the GNU Lesser General Public
@@ -115,12 +115,12 @@ def _convert_result(result): # pragma: no cover
115115
for key, value in json.loads(result.replace('\t', '\\t')).items())
116116

117117

118-
def check_dgii(number): # pragma: no cover
118+
def check_dgii(number, timeout=30): # pragma: no cover
119119
"""Lookup the number using the DGII online web service.
120120
121121
This uses the validation service run by the the Dirección General de
122122
Impuestos Internos, the Dominican Republic tax department to lookup
123-
registration information for the number.
123+
registration information for the number. The timeout is in seconds.
124124
125125
Returns a dict with the following structure::
126126
@@ -137,7 +137,7 @@ def check_dgii(number): # pragma: no cover
137137
# this function isn't automatically tested because it would require
138138
# network access for the tests and unnecessarily load the online service
139139
number = compact(number)
140-
client = get_soap_client(dgii_wsdl)
140+
client = get_soap_client(dgii_wsdl, timeout)
141141
result = '%s' % client.GetContribuyentes(
142142
value=number,
143143
patronBusqueda=0, # search type: 0=by number, 1=by name
@@ -149,15 +149,15 @@ def check_dgii(number): # pragma: no cover
149149
return _convert_result(result)
150150

151151

152-
def search_dgii(keyword, end_at=10, start_at=1): # pragma: no cover
152+
def search_dgii(keyword, end_at=10, start_at=1, timeout=30): # pragma: no cover
153153
"""Search the DGII online web service using the keyword.
154154
155155
This uses the validation service run by the the Dirección General de
156156
Impuestos Internos, the Dominican Republic tax department to search the
157157
registration information using the keyword.
158158
159159
The number of entries returned can be tuned with the `end_at` and
160-
`start_at` arguments.
160+
`start_at` arguments. The timeout is in seconds.
161161
162162
Returns a list of dicts with the following structure::
163163
@@ -177,7 +177,7 @@ def search_dgii(keyword, end_at=10, start_at=1): # pragma: no cover
177177
Will return an empty list if the number is invalid or unknown."""
178178
# this function isn't automatically tested because it would require
179179
# network access for the tests and unnecessarily load the online service
180-
client = get_soap_client(dgii_wsdl)
180+
client = get_soap_client(dgii_wsdl, timeout)
181181
results = '%s' % client.GetContribuyentes(
182182
value=keyword,
183183
patronBusqueda=1, # search type: 0=by number, 1=by name

stdnum/eu/vat.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# vat.py - functions for handling European VAT numbers
22
# coding: utf-8
33
#
4-
# Copyright (C) 2012-2016 Arthur de Jong
4+
# Copyright (C) 2012-2018 Arthur de Jong
55
# Copyright (C) 2015 Lionel Elie Mamane
66
#
77
# This library is free software; you can redistribute it and/or
@@ -109,29 +109,30 @@ def guess_country(number):
109109
if _get_cc_module(cc).is_valid(number)]
110110

111111

112-
def check_vies(number): # pragma: no cover (not part of normal test suite)
112+
def check_vies(number, timeout=30): # pragma: no cover (not part of normal test suite)
113113
"""Query the online European Commission VAT Information Exchange System
114114
(VIES) for validity of the provided number. Note that the service has
115-
usage limitations (see the VIES website for details). This returns a
116-
dict-like object."""
115+
usage limitations (see the VIES website for details). The timeout is in
116+
seconds. This returns a dict-like object."""
117117
# this function isn't automatically tested because it would require
118118
# network access for the tests and unnecessarily load the VIES website
119119
number = compact(number)
120-
client = get_soap_client(vies_wsdl)
120+
client = get_soap_client(vies_wsdl, timeout)
121121
return client.checkVat(number[:2], number[2:])
122122

123123

124-
def check_vies_approx(number, requester): # pragma: no cover
124+
def check_vies_approx(number, requester, timeout=30): # pragma: no cover
125125
"""Query the online European Commission VAT Information Exchange System
126126
(VIES) for validity of the provided number, providing a validity
127127
certificate as proof. You will need to give your own VAT number for this
128128
to work. Note that the service has usage limitations (see the VIES
129-
website for details). This returns a dict-like object."""
129+
website for details). The timeout is in seconds. This returns a dict-like
130+
object."""
130131
# this function isn't automatically tested because it would require
131132
# network access for the tests and unnecessarily load the VIES website
132133
number = compact(number)
133134
requester = compact(requester)
134-
client = get_soap_client(vies_wsdl)
135+
client = get_soap_client(vies_wsdl, timeout)
135136
return client.checkVatApprox(
136137
countryCode=number[:2], vatNumber=number[2:],
137138
requesterCountryCode=requester[:2], requesterVatNumber=requester[2:])

stdnum/tr/tckimlik.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# tckimlik.py - functions for handling T.C. Kimlik No.
22
# coding: utf-8
33
#
4-
# Copyright (C) 2016-2017 Arthur de Jong
4+
# Copyright (C) 2016-2018 Arthur de Jong
55
#
66
# This library is free software; you can redistribute it and/or
77
# modify it under the terms of the GNU Lesser General Public
@@ -89,14 +89,15 @@ def is_valid(number):
8989
return False
9090

9191

92-
def check_kps(number, 10000 name, surname, birth_year): # pragma: no cover
92+
def check_kps(number, name, surname, birth_year, timeout): # pragma: no cover
9393
"""Query the online T.C. Kimlik validation service run by the Directorate
94-
of Population and Citizenship Affairs. This returns a boolean but may
95-
raise a SOAP exception for missing or invalid values."""
94+
of Population and Citizenship Affairs. The timeout is in seconds. This
95+
returns a boolean but may raise a SOAP exception for missing or invalid
96+
values."""
9697
# this function isn't automatically tested because it would require
9798
# network access for the tests and unnecessarily load the online service
9899
number = compact(number)
99-
client = get_soap_client(tckimlik_wsdl)
100+
client = get_soap_client(tckimlik_wsdl, timeout)
100101
result = client.TCKimlikNoDogrula(
101102
TCKimlikNo=number, Ad=name, Soyad=surname, DogumYili=birth_year)
102103
if hasattr(result, 'get'):

stdnum/util.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# util.py - common utility functions
22
# coding: utf-8
33
#
4-
# Copyright (C) 2012-2017 Arthur de Jong
4+
# Copyright (C) 2012-2018 Arthur de Jong
55
#
66
# This library is free software; you can redistribute it and/or
77
# modify it under the terms of the GNU Lesser General Public
@@ -173,20 +173,23 @@ def get_cc_module(cc, name):
173173
_soap_clients = {}
174174

175175

176-
def get_soap_client(wsdlurl): # pragma: no cover (not part of normal test suite)
177-
"""Get a SOAP client for performing requests. The client is cached."""
176+
def get_soap_client(wsdlurl, timeout=30): # pragma: no cover (not part of normal test suite)
177+
"""Get a SOAP client for performing requests. The client is cached. The
178+
timeout is in seconds."""
178179
# this function isn't automatically tested because the functions using
179180
# it are not automatically tested
180-
if wsdlurl not in _soap_clients:
181+
if (wsdlurl, timeout) not in _soap_clients:
181182
# try zeep first
182183
try:
184+
from zeep.transports import Transport
185+
transport = Transport(timeout=timeout)
183186
from zeep import CachingClient
184-
client = CachingClient(wsdlurl).service
187+
client = CachingClient(wsdlurl, transport=transport).service
185188
except ImportError:
186189
# fall back to non-caching zeep client
187190
try:
188191
from zeep import Client
189-
client = Client(wsdlurl).service
192+
client = Client(wsdlurl, transport=transport).service
190193
except ImportError:
191194
# other implementations require passing the proxy config
192195
try:
@@ -196,10 +199,16 @@ def get_soap_client(wsdlurl): # pragma: no cover (not part of normal test suite
196199
# fall back to suds
197200
try:
198201
from suds.client import Client
199-
client = Client(wsdlurl, proxy=getproxies()).service
202+
client = Client(
203+
wsdlurl, proxy=getproxies(), timeout=timeout).service
200204
except ImportError:
201205
# use pysimplesoap as last resort
202-
from pysimplesoap.client import SoapClient
203-
client = SoapClient(wsdl=wsdlurl, proxy=getproxies())
204-
_soap_clients[wsdlurl] = client
205-
return _soap_clients[wsdlurl]
206+
try:
207+
from pysimplesoap.client import SoapClient
208+
client = SoapClient(
209+
wsdl=wsdlurl, proxy=getproxies(), timeout=timeout)
210+
except ImportError:
211+
raise ImportError(
212+
'No SOAP library (such as zeep) found')
213+
_soap_clients[(wsdlurl, timeout)] = client
214+
return _soap_clients[(wsdlurl, timeout)]

0 commit comments

Comments
 (0)
0