python3-commons 0.18.6__tar.gz → 0.18.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python3_commons-0.18.6/src/python3_commons.egg-info → python3_commons-0.18.8}/PKG-INFO +1 -1
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/soap_client.py +96 -105
- {python3_commons-0.18.6 → python3_commons-0.18.8/src/python3_commons.egg-info}/PKG-INFO +1 -1
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.coveragerc +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.devcontainer/Dockerfile +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.devcontainer/devcontainer.json +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.devcontainer/docker-compose.yml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.env_template +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.github/workflows/checks.yml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.github/workflows/python-publish.yaml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.github/workflows/release-on-tag-push.yml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.gitignore +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.pre-commit-config.yaml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/.python-version +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/AUTHORS.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/CHANGELOG.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/LICENSE +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/README.md +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/README.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/Makefile +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/_static/.gitignore +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/authors.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/changelog.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/conf.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/index.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/docs/license.rst +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/pyproject.toml +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/setup.cfg +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/api_client.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/async_functools.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/audit.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/auth.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/cache.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/conf.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/helpers.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/models/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/models/auth.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/models/common.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/models/rbac.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/db/models/users.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/exceptions.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/fs.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/generators.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/helpers.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/log/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/log/filters.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/log/formatters.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/object_storage.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/permissions.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/common.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/json.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/msgpack.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/msgspec.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/SOURCES.txt +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/dependency_links.txt +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/requires.txt +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/top_level.txt +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/integration/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/integration/test_cache.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/integration/test_osc.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/conftest.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/log/__init__.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/log/test_formatters.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/test_async_functools.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/test_audit.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/test_helpers.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/test_msgpack.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/tests/unit/test_msgspec.py +0 -0
- {python3_commons-0.18.6 → python3_commons-0.18.8}/uv.lock +0 -0
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Async SOAP client built on aiohttp + zeep.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
1
|
from __future__ import annotations
|
|
6
2
|
|
|
7
3
|
import asyncio
|
|
8
|
-
import concurrent.futures
|
|
9
4
|
import logging
|
|
10
5
|
import ssl
|
|
11
6
|
from collections.abc import AsyncIterator, Sequence
|
|
@@ -13,10 +8,9 @@ from contextlib import asynccontextmanager
|
|
|
13
8
|
from dataclasses import dataclass
|
|
14
9
|
from typing import TYPE_CHECKING, Any, Self
|
|
15
10
|
|
|
16
|
-
import certifi
|
|
17
|
-
|
|
18
11
|
try:
|
|
19
12
|
import aiohttp
|
|
13
|
+
import certifi
|
|
20
14
|
from aiohttp import ClientSession, ClientTimeout, TCPConnector
|
|
21
15
|
from requests import Response
|
|
22
16
|
from requests.cookies import RequestsCookieJar
|
|
@@ -38,46 +32,38 @@ logger = logging.getLogger(__name__)
|
|
|
38
32
|
|
|
39
33
|
def _make_ssl_context(*, verify: bool) -> ssl.SSLContext | bool:
|
|
40
34
|
if not verify:
|
|
41
|
-
return False
|
|
35
|
+
return False
|
|
42
36
|
|
|
43
37
|
return ssl.create_default_context(cafile=certifi.where())
|
|
44
38
|
|
|
45
39
|
|
|
46
40
|
@dataclass(frozen=True, slots=True)
|
|
47
41
|
class TransportConfig:
|
|
48
|
-
"""Immutable transport settings passed to AsyncTransport."""
|
|
49
|
-
|
|
50
42
|
timeout: int = 300
|
|
51
|
-
"""Total timeout in seconds for WSDL fetches."""
|
|
52
|
-
|
|
53
43
|
operation_timeout: int = 60
|
|
54
|
-
"""Total timeout in seconds for SOAP operation calls."""
|
|
55
|
-
|
|
56
44
|
verify_ssl: bool = True
|
|
57
45
|
proxy: str | None = None
|
|
58
46
|
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
# -------------------------
|
|
49
|
+
# Transport
|
|
50
|
+
# -------------------------
|
|
63
51
|
|
|
64
|
-
Usage::
|
|
65
|
-
|
|
66
|
-
async with soap_client("https://example.com/service?wsdl") as client:
|
|
67
|
-
result = await client.service.SomeOperation(...)
|
|
68
|
-
"""
|
|
69
52
|
|
|
53
|
+
class AsyncTransport(Transport):
|
|
70
54
|
def __init__(
|
|
71
55
|
self,
|
|
72
56
|
*,
|
|
73
57
|
session: ClientSession,
|
|
74
58
|
config: TransportConfig,
|
|
75
|
-
|
|
59
|
+
loop: asyncio.AbstractEventLoop,
|
|
60
|
+
owns_session: bool = False,
|
|
76
61
|
) -> None:
|
|
77
62
|
super().__init__()
|
|
78
63
|
self._session = session
|
|
79
64
|
self._config = config
|
|
80
|
-
self.
|
|
65
|
+
self._loop = loop
|
|
66
|
+
self._owns_session = owns_session
|
|
81
67
|
|
|
82
68
|
@classmethod
|
|
83
69
|
def from_config(
|
|
@@ -85,8 +71,9 @@ class AsyncTransport(Transport):
|
|
|
85
71
|
config: TransportConfig | None = None,
|
|
86
72
|
*,
|
|
87
73
|
session: ClientSession | None = None,
|
|
88
|
-
) ->
|
|
74
|
+
) -> AsyncTransport:
|
|
89
75
|
config = config or TransportConfig()
|
|
76
|
+
loop = asyncio.get_running_loop()
|
|
90
77
|
owns_session = session is None
|
|
91
78
|
|
|
92
79
|
if owns_session:
|
|
@@ -96,7 +83,12 @@ class AsyncTransport(Transport):
|
|
|
96
83
|
headers={'User-Agent': f'Zeep/{get_version()} (www.python-zeep.org)'},
|
|
97
84
|
)
|
|
98
85
|
|
|
99
|
-
return cls(
|
|
86
|
+
return cls(
|
|
87
|
+
session=session,
|
|
88
|
+
config=config,
|
|
89
|
+
loop=loop,
|
|
90
|
+
owns_session=owns_session,
|
|
91
|
+
)
|
|
100
92
|
|
|
101
93
|
async def aclose(self) -> None:
|
|
102
94
|
if self._owns_session:
|
|
@@ -110,7 +102,6 @@ class AsyncTransport(Transport):
|
|
|
110
102
|
|
|
111
103
|
@staticmethod
|
|
112
104
|
def _build_response(response: aiohttp.ClientResponse, body: bytes) -> Response:
|
|
113
|
-
"""Convert an aiohttp response into a requests.Response for zeep."""
|
|
114
105
|
r = Response()
|
|
115
106
|
r.status_code = response.status
|
|
116
107
|
r._content = body # noqa: SLF001
|
|
@@ -127,90 +118,86 @@ class AsyncTransport(Transport):
|
|
|
127
118
|
|
|
128
119
|
return r
|
|
129
120
|
|
|
121
|
+
async def _fetch(self, url: str) -> bytes:
|
|
122
|
+
async with self._session.get(
|
|
123
|
+
url,
|
|
124
|
+
proxy=self._config.proxy,
|
|
125
|
+
timeout=ClientTimeout(total=self._config.timeout),
|
|
126
|
+
) as resp:
|
|
127
|
+
body = await resp.read()
|
|
128
|
+
|
|
129
|
+
if resp.status >= 400:
|
|
130
|
+
raise TransportError(
|
|
131
|
+
status_code=resp.status,
|
|
132
|
+
message=body.decode(errors='ignore'),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return body
|
|
136
|
+
|
|
130
137
|
def load(self, url: str) -> bytes:
|
|
131
138
|
"""
|
|
132
|
-
|
|
139
|
+
Called synchronously by zeep during WSDL parsing.
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
is no cross-loop session sharing with the operational session.
|
|
141
|
+
We safely hop into the main loop.
|
|
136
142
|
"""
|
|
137
143
|
if not url:
|
|
138
144
|
return b''
|
|
139
145
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
) -> Response:
|
|
196
|
-
return await self.post(address, etree_to_string(envelope), headers)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
async def get(
|
|
200
|
-
self,
|
|
201
|
-
address: str,
|
|
202
|
-
params: dict[str, str],
|
|
203
|
-
headers: dict[str, str],
|
|
204
|
-
) -> Response:
|
|
205
|
-
async with self._session.get(
|
|
206
|
-
address,
|
|
207
|
-
params=params,
|
|
208
|
-
headers=headers,
|
|
209
|
-
proxy=self._config.proxy,
|
|
210
|
-
) as resp:
|
|
211
|
-
body = await resp.read()
|
|
212
|
-
|
|
213
|
-
return self._build_response(resp, body)
|
|
146
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
147
|
+
self._fetch(url),
|
|
148
|
+
self._loop,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return future.result()
|
|
152
|
+
|
|
153
|
+
def post_xml(
|
|
154
|
+
self,
|
|
155
|
+
address: str,
|
|
156
|
+
envelope: Any,
|
|
157
|
+
headers: dict[str, str],
|
|
158
|
+
) -> Response:
|
|
159
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
160
|
+
self.post(address, etree_to_string(envelope), headers),
|
|
161
|
+
self._loop,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return future.result()
|
|
165
|
+
|
|
166
|
+
async def post(
|
|
167
|
+
self,
|
|
168
|
+
address: str,
|
|
169
|
+
message: bytes,
|
|
170
|
+
headers: dict[str, str],
|
|
171
|
+
*,
|
|
172
|
+
timeout: int | None = None,
|
|
173
|
+
) -> Response:
|
|
174
|
+
logger.debug('SOAP POST → %s', address)
|
|
175
|
+
|
|
176
|
+
async with self._session.post(
|
|
177
|
+
address,
|
|
178
|
+
data=message,
|
|
179
|
+
headers=headers,
|
|
180
|
+
proxy=self._config.proxy,
|
|
181
|
+
timeout=ClientTimeout(total=timeout) if timeout is not None else None,
|
|
182
|
+
) as resp:
|
|
183
|
+
body = await resp.read()
|
|
184
|
+
logger.debug('SOAP ← %s (%d)', address, resp.status)
|
|
185
|
+
return self._build_response(resp, body)
|
|
186
|
+
|
|
187
|
+
async def get(
|
|
188
|
+
self,
|
|
189
|
+
address: str,
|
|
190
|
+
params: dict[str, str],
|
|
191
|
+
headers: dict[str, str],
|
|
192
|
+
) -> Response:
|
|
193
|
+
async with self._session.get(
|
|
194
|
+
address,
|
|
195
|
+
params=params,
|
|
196
|
+
headers=headers,
|
|
197
|
+
proxy=self._config.proxy,
|
|
198
|
+
) as resp:
|
|
199
|
+
body = await resp.read()
|
|
200
|
+
return self._build_response(resp, body)
|
|
214
201
|
|
|
215
202
|
|
|
216
203
|
def build_soap_client(
|
|
@@ -223,7 +210,11 @@ def build_soap_client(
|
|
|
223
210
|
|
|
224
211
|
raise ValueError(msg)
|
|
225
212
|
|
|
226
|
-
return AsyncClient(
|
|
213
|
+
return AsyncClient(
|
|
214
|
+
wsdl_url,
|
|
215
|
+
transport=transport,
|
|
216
|
+
plugins=list(plugins or []),
|
|
217
|
+
)
|
|
227
218
|
|
|
228
219
|
|
|
229
220
|
@asynccontextmanager
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/msgpack.py
RENAMED
|
File without changes
|
{python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons/serializers/msgspec.py
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python3_commons-0.18.6 → python3_commons-0.18.8}/src/python3_commons.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|