python3-commons 0.18.5__tar.gz → 0.18.6__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.
Files changed (74) hide show
  1. {python3_commons-0.18.5/src/python3_commons.egg-info → python3_commons-0.18.6}/PKG-INFO +4 -1
  2. {python3_commons-0.18.5 → python3_commons-0.18.6}/pyproject.toml +3 -0
  3. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/soap_client.py +77 -70
  4. {python3_commons-0.18.5 → python3_commons-0.18.6/src/python3_commons.egg-info}/PKG-INFO +4 -1
  5. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons.egg-info/requires.txt +3 -0
  6. {python3_commons-0.18.5 → python3_commons-0.18.6}/uv.lock +8 -4
  7. {python3_commons-0.18.5 → python3_commons-0.18.6}/.coveragerc +0 -0
  8. {python3_commons-0.18.5 → python3_commons-0.18.6}/.devcontainer/Dockerfile +0 -0
  9. {python3_commons-0.18.5 → python3_commons-0.18.6}/.devcontainer/devcontainer.json +0 -0
  10. {python3_commons-0.18.5 → python3_commons-0.18.6}/.devcontainer/docker-compose.yml +0 -0
  11. {python3_commons-0.18.5 → python3_commons-0.18.6}/.env_template +0 -0
  12. {python3_commons-0.18.5 → python3_commons-0.18.6}/.github/workflows/checks.yml +0 -0
  13. {python3_commons-0.18.5 → python3_commons-0.18.6}/.github/workflows/python-publish.yaml +0 -0
  14. {python3_commons-0.18.5 → python3_commons-0.18.6}/.github/workflows/release-on-tag-push.yml +0 -0
  15. {python3_commons-0.18.5 → python3_commons-0.18.6}/.gitignore +0 -0
  16. {python3_commons-0.18.5 → python3_commons-0.18.6}/.pre-commit-config.yaml +0 -0
  17. {python3_commons-0.18.5 → python3_commons-0.18.6}/.python-version +0 -0
  18. {python3_commons-0.18.5 → python3_commons-0.18.6}/AUTHORS.rst +0 -0
  19. {python3_commons-0.18.5 → python3_commons-0.18.6}/CHANGELOG.rst +0 -0
  20. {python3_commons-0.18.5 → python3_commons-0.18.6}/LICENSE +0 -0
  21. {python3_commons-0.18.5 → python3_commons-0.18.6}/README.md +0 -0
  22. {python3_commons-0.18.5 → python3_commons-0.18.6}/README.rst +0 -0
  23. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/Makefile +0 -0
  24. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/_static/.gitignore +0 -0
  25. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/authors.rst +0 -0
  26. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/changelog.rst +0 -0
  27. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/conf.py +0 -0
  28. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/index.rst +0 -0
  29. {python3_commons-0.18.5 → python3_commons-0.18.6}/docs/license.rst +0 -0
  30. {python3_commons-0.18.5 → python3_commons-0.18.6}/setup.cfg +0 -0
  31. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/__init__.py +0 -0
  32. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/api_client.py +0 -0
  33. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/async_functools.py +0 -0
  34. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/audit.py +0 -0
  35. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/auth.py +0 -0
  36. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/cache.py +0 -0
  37. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/conf.py +0 -0
  38. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/__init__.py +0 -0
  39. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/helpers.py +0 -0
  40. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/models/__init__.py +0 -0
  41. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/models/auth.py +0 -0
  42. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/models/common.py +0 -0
  43. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/models/rbac.py +0 -0
  44. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/db/models/users.py +0 -0
  45. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/exceptions.py +0 -0
  46. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/fs.py +0 -0
  47. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/generators.py +0 -0
  48. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/helpers.py +0 -0
  49. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/log/__init__.py +0 -0
  50. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/log/filters.py +0 -0
  51. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/log/formatters.py +0 -0
  52. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/object_storage.py +0 -0
  53. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/permissions.py +0 -0
  54. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/serializers/__init__.py +0 -0
  55. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/serializers/common.py +0 -0
  56. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/serializers/json.py +0 -0
  57. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/serializers/msgpack.py +0 -0
  58. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons/serializers/msgspec.py +0 -0
  59. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons.egg-info/SOURCES.txt +0 -0
  60. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons.egg-info/dependency_links.txt +0 -0
  61. {python3_commons-0.18.5 → python3_commons-0.18.6}/src/python3_commons.egg-info/top_level.txt +0 -0
  62. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/__init__.py +0 -0
  63. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/integration/__init__.py +0 -0
  64. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/integration/test_cache.py +0 -0
  65. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/integration/test_osc.py +0 -0
  66. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/__init__.py +0 -0
  67. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/conftest.py +0 -0
  68. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/log/__init__.py +0 -0
  69. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/log/test_formatters.py +0 -0
  70. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/test_async_functools.py +0 -0
  71. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/test_audit.py +0 -0
  72. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/test_helpers.py +0 -0
  73. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/test_msgpack.py +0 -0
  74. {python3_commons-0.18.5 → python3_commons-0.18.6}/tests/unit/test_msgspec.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python3-commons
3
- Version: 0.18.5
3
+ Version: 0.18.6
4
4
  Summary: Re-usable Python3 code
5
5
  Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
6
6
  License-Expression: GPL-3.0
@@ -19,6 +19,7 @@ Provides-Extra: all
19
19
  Requires-Dist: python3_commons[api-client,audit,authn,authz,cache,database,object-storage,soap-client]; extra == "all"
20
20
  Provides-Extra: api-client
21
21
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "api-client"
22
+ Requires-Dist: certifi==2026.4.22; extra == "api-client"
22
23
  Requires-Dist: python3_commons[object-storage]; extra == "api-client"
23
24
  Provides-Extra: audit
24
25
  Requires-Dist: lxml~=6.1.0; extra == "audit"
@@ -26,6 +27,7 @@ Requires-Dist: zeep[async]~=4.3.2; extra == "audit"
26
27
  Requires-Dist: python3_commons[object-storage]; extra == "audit"
27
28
  Provides-Extra: authn
28
29
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "authn"
30
+ Requires-Dist: certifi==2026.4.22; extra == "authn"
29
31
  Requires-Dist: python3_commons[api-client]; extra == "authn"
30
32
  Provides-Extra: authz
31
33
  Requires-Dist: python3_commons[database]; extra == "authz"
@@ -40,6 +42,7 @@ Requires-Dist: aiobotocore~=3.5.0; extra == "object-storage"
40
42
  Requires-Dist: object-storage-client==0.0.23; extra == "object-storage"
41
43
  Provides-Extra: soap-client
42
44
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "soap-client"
45
+ Requires-Dist: certifi==2026.4.22; extra == "soap-client"
43
46
  Requires-Dist: lxml~=6.1.0; extra == "soap-client"
44
47
  Requires-Dist: requests~=2.33.1; extra == "soap-client"
45
48
  Requires-Dist: zeep[async]~=4.3.2; extra == "soap-client"
@@ -29,6 +29,7 @@ all = [
29
29
  ]
30
30
  api-client = [
31
31
  "aiohttp[speedups]>=3.13.5,<3.15.0",
32
+ "certifi==2026.4.22",
32
33
  "python3_commons[object-storage]"
33
34
  ]
34
35
  audit = [
@@ -38,6 +39,7 @@ audit = [
38
39
  ]
39
40
  authn = [
40
41
  "aiohttp[speedups]>=3.13.5,<3.15.0",
42
+ "certifi==2026.4.22",
41
43
  "python3_commons[api-client]"
42
44
  ]
43
45
  authz = [
@@ -57,6 +59,7 @@ object-storage = [
57
59
  ]
58
60
  soap-client = [
59
61
  "aiohttp[speedups]>=3.13.5,<3.15.0",
62
+ "certifi==2026.4.22",
60
63
  "lxml~=6.1.0",
61
64
  "requests~=2.33.1",
62
65
  "zeep[async]~=4.3.2",
@@ -7,11 +7,14 @@ from __future__ import annotations
7
7
  import asyncio
8
8
  import concurrent.futures
9
9
  import logging
10
+ import ssl
10
11
  from collections.abc import AsyncIterator, Sequence
11
12
  from contextlib import asynccontextmanager
12
13
  from dataclasses import dataclass
13
14
  from typing import TYPE_CHECKING, Any, Self
14
15
 
16
+ import certifi
17
+
15
18
  try:
16
19
  import aiohttp
17
20
  from aiohttp import ClientSession, ClientTimeout, TCPConnector
@@ -33,6 +36,13 @@ if TYPE_CHECKING:
33
36
  logger = logging.getLogger(__name__)
34
37
 
35
38
 
39
+ def _make_ssl_context(*, verify: bool) -> ssl.SSLContext | bool:
40
+ if not verify:
41
+ return False # aiohttp accepts False to disable verification
42
+
43
+ return ssl.create_default_context(cafile=certifi.where())
44
+
45
+
36
46
  @dataclass(frozen=True, slots=True)
37
47
  class TransportConfig:
38
48
  """Immutable transport settings passed to AsyncTransport."""
@@ -58,11 +68,11 @@ class AsyncTransport(Transport):
58
68
  """
59
69
 
60
70
  def __init__(
61
- self,
62
- *,
63
- session: ClientSession,
64
- config: TransportConfig,
65
- _owns_session: bool = False,
71
+ self,
72
+ *,
73
+ session: ClientSession,
74
+ config: TransportConfig,
75
+ _owns_session: bool = False,
66
76
  ) -> None:
67
77
  super().__init__()
68
78
  self._session = session
@@ -71,23 +81,17 @@ class AsyncTransport(Transport):
71
81
 
72
82
  @classmethod
73
83
  def from_config(
74
- cls,
75
- config: TransportConfig | None = None,
76
- *,
77
- session: ClientSession | None = None,
84
+ cls,
85
+ config: TransportConfig | None = None,
86
+ *,
87
+ session: ClientSession | None = None,
78
88
  ) -> Self:
79
- """
80
- Create a transport, optionally sharing an existing ClientSession.
81
-
82
- If *session* is omitted the transport owns (and will close) the
83
- session it creates.
84
- """
85
89
  config = config or TransportConfig()
86
90
  owns_session = session is None
87
91
 
88
92
  if owns_session:
89
93
  session = ClientSession(
90
- connector=TCPConnector(ssl=config.verify_ssl),
94
+ connector=TCPConnector(ssl=_make_ssl_context(verify=config.verify_ssl)),
91
95
  timeout=ClientTimeout(total=config.operation_timeout),
92
96
  headers={'User-Agent': f'Zeep/{get_version()} (www.python-zeep.org)'},
93
97
  )
@@ -136,7 +140,7 @@ class AsyncTransport(Transport):
136
140
  async def _fetch() -> bytes:
137
141
  async with (
138
142
  ClientSession(
139
- connector=TCPConnector(ssl=self._config.verify_ssl),
143
+ connector=TCPConnector(ssl=_make_ssl_context(verify=self._config.verify_ssl)),
140
144
  timeout=ClientTimeout(total=self._config.timeout),
141
145
  headers={'User-Agent': f'Zeep/{get_version()} (www.python-zeep.org)'},
142
146
  ) as session,
@@ -159,57 +163,60 @@ class AsyncTransport(Transport):
159
163
  with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
160
164
  return pool.submit(asyncio.run, _fetch()).result()
161
165
 
162
- async def post(
163
- self,
164
- address: str,
165
- message: bytes,
166
- headers: dict[str, str],
167
- *,
168
- timeout: int | None = None,
169
- ) -> Response:
170
- logger.debug('SOAP POST → %s\n%s', address, message)
171
-
172
- async with self._session.post(
173
- address,
174
- data=message,
175
- headers=headers,
176
- proxy=self._config.proxy,
177
- timeout=ClientTimeout(total=timeout) if timeout is not None else None,
178
- ) as resp:
179
- body = await resp.read()
180
- logger.debug('SOAP %s (HTTP %d)\n%s', address, resp.status, body)
181
-
182
- return self._build_response(resp, body)
183
-
184
- async def post_xml(
185
- self,
186
- address: str,
187
- envelope: Any,
188
- headers: dict[str, str],
189
- ) -> Response:
190
- return await self.post(address, etree_to_string(envelope), headers)
191
-
192
- async def get(
193
- self,
194
- address: str,
195
- params: dict[str, str],
196
- headers: dict[str, str],
197
- ) -> Response:
198
- async with self._session.get(
199
- address,
200
- params=params,
201
- headers=headers,
202
- proxy=self._config.proxy,
203
- ) as resp:
204
- body = await resp.read()
205
-
206
- return self._build_response(resp, body)
166
+
167
+ async def post(
168
+ self,
169
+ address: str,
170
+ message: bytes,
171
+ headers: dict[str, str],
172
+ *,
173
+ timeout: int | None = None,
174
+ ) -> Response:
175
+ logger.debug('SOAP POST → %s\n%s', address, message)
176
+
177
+ async with self._session.post(
178
+ address,
179
+ data=message,
180
+ headers=headers,
181
+ proxy=self._config.proxy,
182
+ timeout=ClientTimeout(total=timeout) if timeout is not None else None,
183
+ ) as resp:
184
+ body = await resp.read()
185
+ logger.debug('SOAP ← %s (HTTP %d)\n%s', address, resp.status, body)
186
+
187
+ return self._build_response(resp, body)
188
+
189
+
190
+ async def post_xml(
191
+ self,
192
+ address: str,
193
+ envelope: Any,
194
+ headers: dict[str, str],
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)
207
214
 
208
215
 
209
216
  def build_soap_client(
210
- wsdl_url: str,
211
- transport: AsyncTransport,
212
- plugins: Sequence[Plugin] | None = None,
217
+ wsdl_url: str,
218
+ transport: AsyncTransport,
219
+ plugins: Sequence[Plugin] | None = None,
213
220
  ) -> AsyncClient:
214
221
  if not wsdl_url:
215
222
  msg = 'wsdl_url must be a non-empty string.'
@@ -221,11 +228,11 @@ def build_soap_client(
221
228
 
222
229
  @asynccontextmanager
223
230
  async def soap_client(
224
- wsdl_url: str,
225
- *,
226
- config: TransportConfig | None = None,
227
- session: ClientSession | None = None,
228
- plugins: Sequence[Plugin] | None = None,
231
+ wsdl_url: str,
232
+ *,
233
+ config: TransportConfig | None = None,
234
+ session: ClientSession | None = None,
235
+ plugins: Sequence[Plugin] | None = None,
229
236
  ) -> AsyncIterator[AsyncClient]:
230
237
  """
231
238
  Async context manager yielding a ready-to-use zeep AsyncClient.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python3-commons
3
- Version: 0.18.5
3
+ Version: 0.18.6
4
4
  Summary: Re-usable Python3 code
5
5
  Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
6
6
  License-Expression: GPL-3.0
@@ -19,6 +19,7 @@ Provides-Extra: all
19
19
  Requires-Dist: python3_commons[api-client,audit,authn,authz,cache,database,object-storage,soap-client]; extra == "all"
20
20
  Provides-Extra: api-client
21
21
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "api-client"
22
+ Requires-Dist: certifi==2026.4.22; extra == "api-client"
22
23
  Requires-Dist: python3_commons[object-storage]; extra == "api-client"
23
24
  Provides-Extra: audit
24
25
  Requires-Dist: lxml~=6.1.0; extra == "audit"
@@ -26,6 +27,7 @@ Requires-Dist: zeep[async]~=4.3.2; extra == "audit"
26
27
  Requires-Dist: python3_commons[object-storage]; extra == "audit"
27
28
  Provides-Extra: authn
28
29
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "authn"
30
+ Requires-Dist: certifi==2026.4.22; extra == "authn"
29
31
  Requires-Dist: python3_commons[api-client]; extra == "authn"
30
32
  Provides-Extra: authz
31
33
  Requires-Dist: python3_commons[database]; extra == "authz"
@@ -40,6 +42,7 @@ Requires-Dist: aiobotocore~=3.5.0; extra == "object-storage"
40
42
  Requires-Dist: object-storage-client==0.0.23; extra == "object-storage"
41
43
  Provides-Extra: soap-client
42
44
  Requires-Dist: aiohttp[speedups]<3.15.0,>=3.13.5; extra == "soap-client"
45
+ Requires-Dist: certifi==2026.4.22; extra == "soap-client"
43
46
  Requires-Dist: lxml~=6.1.0; extra == "soap-client"
44
47
  Requires-Dist: requests~=2.33.1; extra == "soap-client"
45
48
  Requires-Dist: zeep[async]~=4.3.2; extra == "soap-client"
@@ -7,6 +7,7 @@ python3_commons[api-client,audit,authn,authz,cache,database,object-storage,soap-
7
7
 
8
8
  [api-client]
9
9
  aiohttp[speedups]<3.15.0,>=3.13.5
10
+ certifi==2026.4.22
10
11
  python3_commons[object-storage]
11
12
 
12
13
  [audit]
@@ -16,6 +17,7 @@ python3_commons[object-storage]
16
17
 
17
18
  [authn]
18
19
  aiohttp[speedups]<3.15.0,>=3.13.5
20
+ certifi==2026.4.22
19
21
  python3_commons[api-client]
20
22
 
21
23
  [authz]
@@ -35,6 +37,7 @@ object-storage-client==0.0.23
35
37
 
36
38
  [soap-client]
37
39
  aiohttp[speedups]<3.15.0,>=3.13.5
40
+ certifi==2026.4.22
38
41
  lxml~=6.1.0
39
42
  requests~=2.33.1
40
43
  zeep[async]~=4.3.2
@@ -1051,6 +1051,7 @@ all = [
1051
1051
  { name = "aiobotocore" },
1052
1052
  { name = "aiohttp", extra = ["speedups"] },
1053
1053
  { name = "asyncpg" },
1054
+ { name = "certifi" },
1054
1055
  { name = "lxml" },
1055
1056
  { name = "object-storage-client" },
1056
1057
  { name = "requests" },
@@ -1061,7 +1062,7 @@ all = [
1061
1062
  api-client = [
1062
1063
  { name = "aiobotocore" },
1063
1064
  { name = "aiohttp", extra = ["speedups"] },
1064
- { name = "lxml" },
1065
+ { name = "certifi" },
1065
1066
  { name = "object-storage-client" },
1066
1067
  ]
1067
1068
  audit = [
@@ -1073,14 +1074,14 @@ audit = [
1073
1074
  authn = [
1074
1075
  { name = "aiobotocore" },
1075
1076
  { name = "aiohttp", extra = ["speedups"] },
1076
- { name = "lxml" },
1077
+ { name = "certifi" },
1077
1078
  { name = "object-storage-client" },
1078
1079
  ]
1079
1080
  authz = [
1080
1081
  { name = "aiobotocore" },
1081
1082
  { name = "aiohttp", extra = ["speedups"] },
1082
1083
  { name = "asyncpg" },
1083
- { name = "lxml" },
1084
+ { name = "certifi" },
1084
1085
  { name = "object-storage-client" },
1085
1086
  { name = "sqlalchemy", extra = ["asyncio"] },
1086
1087
  ]
@@ -1097,6 +1098,7 @@ object-storage = [
1097
1098
  ]
1098
1099
  soap-client = [
1099
1100
  { name = "aiohttp", extra = ["speedups"] },
1101
+ { name = "certifi" },
1100
1102
  { name = "lxml" },
1101
1103
  { name = "requests" },
1102
1104
  { name = "zeep", extra = ["async"] },
@@ -1126,7 +1128,9 @@ requires-dist = [
1126
1128
  { name = "aiohttp", extras = ["speedups"], marker = "extra == 'authn'", specifier = ">=3.13.5,<3.15.0" },
1127
1129
  { name = "aiohttp", extras = ["speedups"], marker = "extra == 'soap-client'", specifier = ">=3.13.5,<3.15.0" },
1128
1130
  { name = "asyncpg", marker = "extra == 'database'", specifier = "~=0.31.0" },
1129
- { name = "lxml", marker = "extra == 'api-client'", specifier = "~=6.1.0" },
1131
+ { name = "certifi", marker = "extra == 'api-client'", specifier = "==2026.4.22" },
1132
+ { name = "certifi", marker = "extra == 'authn'", specifier = "==2026.4.22" },
1133
+ { name = "certifi", marker = "extra == 'soap-client'", specifier = "==2026.4.22" },
1130
1134
  { name = "lxml", marker = "extra == 'audit'", specifier = "~=6.1.0" },
1131
1135
  { name = "lxml", marker = "extra == 'soap-client'", specifier = "~=6.1.0" },
1132
1136
  { name = "msgpack", specifier = "~=1.1.2" },