|
26 | 26 | from .managers import NotificationManager, PullPointManager
|
27 | 27 | from .settings import DEFAULT_SETTINGS
|
28 | 28 | from .transport import ASYNC_TRANSPORT
|
| 29 | +from .types import FastDateTime |
29 | 30 | from .util import create_no_verify_ssl_context, normalize_url, path_isfile, utcnow
|
30 | 31 | from .wrappers import retry_connection_error # noqa: F401
|
31 | 32 |
|
@@ -80,10 +81,44 @@ def apply(self, envelope, headers):
|
80 | 81 | return result
|
81 | 82 |
|
82 | 83 |
|
83 |
| -@lru_cache(maxsize=128) |
84 |
| -def _cached_document(url: str) -> Document: |
| 84 | +_DOCUMENT_CACHE: dict[str, Document] = {} |
| 85 | + |
| 86 | +original_load = Document.load |
| 87 | + |
| 88 | + |
| 89 | +class DocumentWithDeferredLoad(Document): |
| 90 | + def load(self, *args: Any, **kwargs: Any) -> None: |
| 91 | + """Deferred load of the document.""" |
| 92 | + |
| 93 | + def original_load(self, *args: Any, **kwargs: Any) -> None: |
| 94 | + """Original load of the document.""" |
| 95 | + return original_load(self, *args, **kwargs) |
| 96 | + |
| 97 | + |
| 98 | +async def _cached_document(url: str) -> Document: |
85 | 99 | """Load external XML document from disk."""
|
86 |
| - return Document(url, ASYNC_TRANSPORT, settings=DEFAULT_SETTINGS) |
| 100 | + if url in _DOCUMENT_CACHE: |
| 101 | + return _DOCUMENT_CACHE[url] |
| 102 | + loop = asyncio.get_event_loop() |
| 103 | + |
| 104 | + def _load_document() -> DocumentWithDeferredLoad: |
| 105 | + document = DocumentWithDeferredLoad(url, ASYNC_TRANSPORT, DEFAULT_SETTINGS) |
| 106 | + # Override the default datetime type to use FastDateTime |
| 107 | + # This is a workaround for the following issue: |
| 108 | + # https://github.com/mvantellingen/python-zeep/pull/1370 |
| 109 | + schema = document.types.documents.get_by_namespace( |
| 110 | + "http://www.w3.org/2001/XMLSchema", False |
| 111 | + )[0] |
| 112 | + instance = FastDateTime(is_global=True) |
| 113 | + schema.register_type(FastDateTime._default_qname, instance) |
| 114 | + document.types.add_documents([None], url) |
| 115 | + # Perform the original load |
| 116 | + document.original_load(url) |
| 117 | + return document |
| 118 | + |
| 119 | + document = await loop.run_in_executor(None, _load_document) |
| 120 | + _DOCUMENT_CACHE[url] = document |
| 121 | + return document |
87 | 122 |
|
88 | 123 |
|
89 | 124 | class ZeepAsyncClient(BaseZeepAsyncClient):
|
@@ -201,9 +236,7 @@ async def setup(self):
|
201 | 236 | wsse = UsernameDigestTokenDtDiff(
|
202 | 237 | self.user, self.passwd, dt_diff=self.dt_diff, use_digest=self.encrypt
|
203 | 238 | )
|
204 |
| - self.document = await self.loop.run_in_executor( |
205 |
| - None, _cached_document, self.url |
206 |
| - ) |
| 239 | + self.document = await _cached_document(self.url) |
207 | 240 | self.zeep_client_authless = ZeepAsyncClient(
|
208 | 241 | wsdl=self.document,
|
209 | 242 | transport=self.transport,
|
|
0 commit comments