python3-commons 0.19.0__tar.gz → 0.20.0__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 (76) hide show
  1. {python3_commons-0.19.0/src/python3_commons.egg-info → python3_commons-0.20.0}/PKG-INFO +2 -2
  2. {python3_commons-0.19.0 → python3_commons-0.20.0}/pyproject.toml +1 -1
  3. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/auth.py +34 -17
  4. {python3_commons-0.19.0 → python3_commons-0.20.0/src/python3_commons.egg-info}/PKG-INFO +2 -2
  5. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons.egg-info/requires.txt +1 -1
  6. {python3_commons-0.19.0 → python3_commons-0.20.0}/uv.lock +19 -18
  7. {python3_commons-0.19.0 → python3_commons-0.20.0}/.coveragerc +0 -0
  8. {python3_commons-0.19.0 → python3_commons-0.20.0}/.devcontainer/Dockerfile +0 -0
  9. {python3_commons-0.19.0 → python3_commons-0.20.0}/.devcontainer/devcontainer.json +0 -0
  10. {python3_commons-0.19.0 → python3_commons-0.20.0}/.devcontainer/docker-compose.yml +0 -0
  11. {python3_commons-0.19.0 → python3_commons-0.20.0}/.env_template +0 -0
  12. {python3_commons-0.19.0 → python3_commons-0.20.0}/.github/workflows/checks.yml +0 -0
  13. {python3_commons-0.19.0 → python3_commons-0.20.0}/.github/workflows/python-publish.yaml +0 -0
  14. {python3_commons-0.19.0 → python3_commons-0.20.0}/.github/workflows/release-on-tag-push.yml +0 -0
  15. {python3_commons-0.19.0 → python3_commons-0.20.0}/.gitignore +0 -0
  16. {python3_commons-0.19.0 → python3_commons-0.20.0}/.pre-commit-config.yaml +0 -0
  17. {python3_commons-0.19.0 → python3_commons-0.20.0}/.python-version +0 -0
  18. {python3_commons-0.19.0 → python3_commons-0.20.0}/AUTHORS.rst +0 -0
  19. {python3_commons-0.19.0 → python3_commons-0.20.0}/CHANGELOG.rst +0 -0
  20. {python3_commons-0.19.0 → python3_commons-0.20.0}/LICENSE +0 -0
  21. {python3_commons-0.19.0 → python3_commons-0.20.0}/README.md +0 -0
  22. {python3_commons-0.19.0 → python3_commons-0.20.0}/README.rst +0 -0
  23. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/Makefile +0 -0
  24. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/_static/.gitignore +0 -0
  25. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/authors.rst +0 -0
  26. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/changelog.rst +0 -0
  27. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/conf.py +0 -0
  28. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/index.rst +0 -0
  29. {python3_commons-0.19.0 → python3_commons-0.20.0}/docs/license.rst +0 -0
  30. {python3_commons-0.19.0 → python3_commons-0.20.0}/setup.cfg +0 -0
  31. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/__init__.py +0 -0
  32. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/api_client.py +0 -0
  33. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/async_functools.py +0 -0
  34. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/audit.py +0 -0
  35. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/cache.py +0 -0
  36. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/conf.py +0 -0
  37. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/__init__.py +0 -0
  38. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/helpers.py +0 -0
  39. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/models/__init__.py +0 -0
  40. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/models/auth.py +0 -0
  41. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/models/common.py +0 -0
  42. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/models/rbac.py +0 -0
  43. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/db/models/users.py +0 -0
  44. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/exceptions.py +0 -0
  45. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/fs.py +0 -0
  46. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/generators.py +0 -0
  47. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/helpers.py +0 -0
  48. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/log/__init__.py +0 -0
  49. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/log/filters.py +0 -0
  50. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/log/formatters.py +0 -0
  51. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/object_storage.py +0 -0
  52. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/permissions.py +0 -0
  53. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/serializers/__init__.py +0 -0
  54. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/serializers/common.py +0 -0
  55. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/serializers/json.py +0 -0
  56. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/serializers/msgpack.py +0 -0
  57. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/serializers/msgspec.py +0 -0
  58. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons/soap_client.py +0 -0
  59. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons.egg-info/SOURCES.txt +0 -0
  60. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons.egg-info/dependency_links.txt +0 -0
  61. {python3_commons-0.19.0 → python3_commons-0.20.0}/src/python3_commons.egg-info/top_level.txt +0 -0
  62. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/__init__.py +0 -0
  63. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/integration/__init__.py +0 -0
  64. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/integration/conftest.py +0 -0
  65. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/integration/test_auth.py +0 -0
  66. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/integration/test_cache.py +0 -0
  67. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/integration/test_osc.py +0 -0
  68. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/__init__.py +0 -0
  69. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/conftest.py +0 -0
  70. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/log/__init__.py +0 -0
  71. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/log/test_formatters.py +0 -0
  72. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/test_async_functools.py +0 -0
  73. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/test_audit.py +0 -0
  74. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/test_helpers.py +0 -0
  75. {python3_commons-0.19.0 → python3_commons-0.20.0}/tests/unit/test_msgpack.py +0 -0
  76. {python3_commons-0.19.0 → python3_commons-0.20.0}/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.19.0
3
+ Version: 0.20.0
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
@@ -36,7 +36,7 @@ Provides-Extra: cache
36
36
  Requires-Dist: valkey[libvalkey]~=6.1.1; extra == "cache"
37
37
  Provides-Extra: database
38
38
  Requires-Dist: asyncpg~=0.31.0; extra == "database"
39
- Requires-Dist: SQLAlchemy[asyncio]~=2.0.49; extra == "database"
39
+ Requires-Dist: SQLAlchemy[asyncio]~=2.0.50; extra == "database"
40
40
  Provides-Extra: object-storage
41
41
  Requires-Dist: aiobotocore~=3.7.0; extra == "object-storage"
42
42
  Requires-Dist: object-storage-client==0.0.30; extra == "object-storage"
@@ -51,7 +51,7 @@ cache = [
51
51
  ]
52
52
  database = [
53
53
  "asyncpg~=0.31.0",
54
- "SQLAlchemy[asyncio]~=2.0.49"
54
+ "SQLAlchemy[asyncio]~=2.0.50"
55
55
  ]
56
56
  object-storage = [
57
57
  "aiobotocore~=3.7.0",
@@ -16,8 +16,6 @@ except ImportError as e:
16
16
 
17
17
  import msgspec
18
18
 
19
- from python3_commons.conf import oidc_settings
20
-
21
19
  logger = logging.getLogger(__name__)
22
20
  _OIDC_LOCK = threading.Lock()
23
21
 
@@ -81,20 +79,24 @@ class OIDCClient:
81
79
  timeout: float = 10.0,
82
80
  verify_ssl: bool = True,
83
81
  connection_limit: int = 100,
82
+ authority_internal_host: HttpUrl | None = None,
84
83
  ) -> None:
85
- if oidc_settings.authority_internal_host:
86
- authority_url = replace_origin(authority_url, oidc_settings.authority_internal_host)
84
+ if authority_internal_host:
85
+ authority_url = replace_origin(authority_url, authority_internal_host)
87
86
 
88
87
  self._authority_url = authority_url
88
+ self._authority_internal_host = authority_internal_host
89
89
  self._client_id = client_id
90
90
  self._client_secret = client_secret
91
- self._oidc_config: Mapping[str, Any] | None = None
92
91
 
93
92
  self._connection_limit = connection_limit
94
93
  self._session: aiohttp.ClientSession | None = None
95
94
  self._timeout = timeout
96
95
  self._verify_ssl = verify_ssl
97
96
 
97
+ self._config: Mapping[str, Any] | None = None
98
+ self._jwks: Mapping[str, Any] | None = None
99
+
98
100
  def get_session(self) -> aiohttp.ClientSession:
99
101
  if self._session:
100
102
  return self._session
@@ -119,7 +121,7 @@ class OIDCClient:
119
121
  if self._session:
120
122
  await self._session.close()
121
123
 
122
- async def _fetch_openid_config(self) -> dict:
124
+ async def _fetch_config(self) -> dict:
123
125
  """
124
126
  Fetch the OpenID configuration (including JWKS URI) from OIDC authority.
125
127
  """
@@ -139,7 +141,20 @@ class OIDCClient:
139
141
 
140
142
  return await response.json()
141
143
 
142
- async def fetch_jwks(self, jwks_uri: str) -> dict:
144
+ async def get_config(self) -> Mapping[str, Any]:
145
+ if self._config:
146
+ return self._config
147
+
148
+ with _OIDC_LOCK:
149
+ if self._config:
150
+ return self._config
151
+
152
+ config = await self._fetch_config()
153
+ self._config = config
154
+
155
+ return config
156
+
157
+ async def _fetch_jwks(self, jwks_uri: str) -> dict:
143
158
  """
144
159
  Fetch the JSON Web Key Set (JWKS) for validating the token's signature.
145
160
  """
@@ -147,7 +162,7 @@ class OIDCClient:
147
162
  msg = 'ClientSession not initialized'
148
163
  raise RuntimeError(msg)
149
164
 
150
- if authority_internal_host := oidc_settings.authority_internal_host:
165
+ if authority_internal_host := self._authority_internal_host:
151
166
  logger.debug('Received jwks_uri: %s', jwks_uri)
152
167
  logger.debug('Replacing OIDC authority host with: %s', authority_internal_host)
153
168
  jwks_uri = str(replace_origin(HttpUrl(jwks_uri), authority_internal_host))
@@ -161,18 +176,20 @@ class OIDCClient:
161
176
 
162
177
  return await response.json()
163
178
 
164
- async def get_openid_config(self) -> Mapping[str, Any]:
165
- if self._oidc_config:
166
- return self._oidc_config
179
+ async def get_jwks(self) -> Mapping[str, Any]:
180
+ if self._jwks:
181
+ return self._jwks
167
182
 
168
183
  with _OIDC_LOCK:
169
- if self._oidc_config:
170
- return self._oidc_config
184
+ if self._jwks:
185
+ return self._jwks
186
+
187
+ oidc_config = await self.get_config()
171
188
 
172
- oidc_config = await self._fetch_openid_config()
173
- self._oidc_config = oidc_config
189
+ jwks = await self._fetch_jwks(oidc_config['jwks_uri'])
190
+ self._jwks = jwks
174
191
 
175
- return oidc_config
192
+ return jwks
176
193
 
177
194
  async def fetch_token(
178
195
  self,
@@ -196,7 +213,7 @@ class OIDCClient:
196
213
  if self._client_secret:
197
214
  data['client_secret'] = self._client_secret
198
215
 
199
- openid_config = await self.get_openid_config()
216
+ openid_config = await self.get_config()
200
217
 
201
218
  try:
202
219
  async with self._session.post(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python3-commons
3
- Version: 0.19.0
3
+ Version: 0.20.0
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
@@ -36,7 +36,7 @@ Provides-Extra: cache
36
36
  Requires-Dist: valkey[libvalkey]~=6.1.1; extra == "cache"
37
37
  Provides-Extra: database
38
38
  Requires-Dist: asyncpg~=0.31.0; extra == "database"
39
- Requires-Dist: SQLAlchemy[asyncio]~=2.0.49; extra == "database"
39
+ Requires-Dist: SQLAlchemy[asyncio]~=2.0.50; extra == "database"
40
40
  Provides-Extra: object-storage
41
41
  Requires-Dist: aiobotocore~=3.7.0; extra == "object-storage"
42
42
  Requires-Dist: object-storage-client==0.0.30; extra == "object-storage"
@@ -29,7 +29,7 @@ valkey[libvalkey]~=6.1.1
29
29
 
30
30
  [database]
31
31
  asyncpg~=0.31.0
32
- SQLAlchemy[asyncio]~=2.0.49
32
+ SQLAlchemy[asyncio]~=2.0.50
33
33
 
34
34
  [object-storage]
35
35
  aiobotocore~=3.7.0
@@ -1171,7 +1171,7 @@ requires-dist = [
1171
1171
  { name = "python3-commons", extras = ["database"], marker = "extra == 'authz'" },
1172
1172
  { name = "python3-commons", extras = ["object-storage"], marker = "extra == 'audit'" },
1173
1173
  { name = "requests", marker = "extra == 'soap-client'", specifier = "~=2.34.2" },
1174
- { name = "sqlalchemy", extras = ["asyncio"], marker = "extra == 'database'", specifier = "~=2.0.49" },
1174
+ { name = "sqlalchemy", extras = ["asyncio"], marker = "extra == 'database'", specifier = "~=2.0.50" },
1175
1175
  { name = "valkey", extras = ["libvalkey"], marker = "extra == 'cache'", specifier = "~=6.1.1" },
1176
1176
  { name = "zeep", extras = ["async"], marker = "extra == 'audit'", specifier = "~=4.3.2" },
1177
1177
  { name = "zeep", extras = ["async"], marker = "extra == 'soap-client'", specifier = "~=4.3.2" },
@@ -1331,28 +1331,29 @@ wheels = [
1331
1331
 
1332
1332
  [[package]]
1333
1333
  name = "sqlalchemy"
1334
- version = "2.0.49"
1334
+ version = "2.0.50"
1335
1335
  source = { registry = "https://pypi.org/simple" }
1336
1336
  dependencies = [
1337
1337
  { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" },
1338
1338
  { name = "typing-extensions" },
1339
1339
  ]
1340
- sdist = { url = "https://files.pythonhosted.org/packages/09/45/461788f35e0364a8da7bda51a1fe1b09762d0c32f12f63727998d85a873b/sqlalchemy-2.0.49.tar.gz", hash = "sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f", size = 9898221, upload-time = "2026-04-03T16:38:11.704Z" }
1341
- wheels = [
1342
- { url = "https://files.pythonhosted.org/packages/55/33/bf28f618c0a9597d14e0b9ee7d1e0622faff738d44fe986ee287cdf1b8d0/sqlalchemy-2.0.49-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e", size = 2156356, upload-time = "2026-04-03T16:53:09.914Z" },
1343
- { url = "https://files.pythonhosted.org/packages/d1/a7/5f476227576cb8644650eff68cc35fa837d3802b997465c96b8340ced1e2/sqlalchemy-2.0.49-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a", size = 3276486, upload-time = "2026-04-03T17:07:46.9Z" },
1344
- { url = "https://files.pythonhosted.org/packages/2e/84/efc7c0bf3a1c5eef81d397f6fddac855becdbb11cb38ff957888603014a7/sqlalchemy-2.0.49-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066", size = 3281479, upload-time = "2026-04-03T17:12:32.226Z" },
1345
- { url = "https://files.pythonhosted.org/packages/91/68/bb406fa4257099c67bd75f3f2261b129c63204b9155de0d450b37f004698/sqlalchemy-2.0.49-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187", size = 3226269, upload-time = "2026-04-03T17:07:48.678Z" },
1346
- { url = "https://files.pythonhosted.org/packages/67/84/acb56c00cca9f251f437cb49e718e14f7687505749ea9255d7bd8158a6df/sqlalchemy-2.0.49-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401", size = 3248260, upload-time = "2026-04-03T17:12:34.381Z" },
1347
- { url = "https://files.pythonhosted.org/packages/56/19/6a20ea25606d1efd7bd1862149bb2a22d1451c3f851d23d887969201633f/sqlalchemy-2.0.49-cp314-cp314-win32.whl", hash = "sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5", size = 2118463, upload-time = "2026-04-03T17:05:47.093Z" },
1348
- { url = "https://files.pythonhosted.org/packages/cf/4f/8297e4ed88e80baa1f5aa3c484a0ee29ef3c69c7582f206c916973b75057/sqlalchemy-2.0.49-cp314-cp314-win_amd64.whl", hash = "sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5", size = 2144204, upload-time = "2026-04-03T17:05:48.694Z" },
1349
- { url = "https://files.pythonhosted.org/packages/1f/33/95e7216df810c706e0cd3655a778604bbd319ed4f43333127d465a46862d/sqlalchemy-2.0.49-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977", size = 3565474, upload-time = "2026-04-03T16:58:35.128Z" },
1350
- { url = "https://files.pythonhosted.org/packages/0c/a4/ed7b18d8ccf7f954a83af6bb73866f5bc6f5636f44c7731fbb741f72cc4f/sqlalchemy-2.0.49-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01", size = 3530567, upload-time = "2026-04-03T17:06:04.587Z" },
1351
- { url = "https://files.pythonhosted.org/packages/73/a3/20faa869c7e21a827c4a2a42b41353a54b0f9f5e96df5087629c306df71e/sqlalchemy-2.0.49-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61", size = 3474282, upload-time = "2026-04-03T16:58:37.131Z" },
1352
- { url = "https://files.pythonhosted.org/packages/b7/50/276b9a007aa0764304ad467eceb70b04822dc32092492ee5f322d559a4dc/sqlalchemy-2.0.49-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a", size = 3480406, upload-time = "2026-04-03T17:06:07.176Z" },
1353
- { url = "https://files.pythonhosted.org/packages/e5/c3/c80fcdb41905a2df650c2a3e0337198b6848876e63d66fe9188ef9003d24/sqlalchemy-2.0.49-cp314-cp314t-win32.whl", hash = "sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158", size = 2149151, upload-time = "2026-04-03T17:02:07.281Z" },
1354
- { url = "https://files.pythonhosted.org/packages/05/52/9f1a62feab6ed368aff068524ff414f26a6daebc7361861035ae00b05530/sqlalchemy-2.0.49-cp314-cp314t-win_amd64.whl", hash = "sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7", size = 2184178, upload-time = "2026-04-03T17:02:08.623Z" },
1355
- { url = "https://files.pythonhosted.org/packages/e5/30/8519fdde58a7bdf155b714359791ad1dc018b47d60269d5d160d311fdc36/sqlalchemy-2.0.49-py3-none-any.whl", hash = "sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0", size = 1942158, upload-time = "2026-04-03T16:53:44.135Z" },
1340
+ sdist = { url = "https://files.pythonhosted.org/packages/57/da/6fbf010c8ebb347679d0d100b22fe9ba5e13fd04046c5df7280d2f0bf706/sqlalchemy-2.0.50.tar.gz", hash = "sha256:af5607d11ef90fd6a5c0549fe0045dce1663d427426bcfb506dcb5346a85a3b9", size = 9907424, upload-time = "2026-05-24T19:20:04.018Z" }
1341
+ wheels = [
1342
+ { url = "https://files.pythonhosted.org/packages/df/32/10ac51b4be7cdecd7e93d069251c86dfbf70b7adbd7c67b48ccea6c49e1c/sqlalchemy-2.0.50-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c966932507a4d7d0a37314927dbfcd89720e3f37d2a1e3352e7ae7939fa8e8a0", size = 2158519, upload-time = "2026-05-24T19:27:56.472Z" },
1343
+ { url = "https://files.pythonhosted.org/packages/5a/76/e703d2f7681d7d66c4c891af3f07c7ccf4c76ad7f18351de035b5eda007a/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:faffef4bcc20a1892e65e155293d99d60855bbbc79250ab712819cfd56a8e6bb", size = 3282063, upload-time = "2026-05-24T20:09:38.57Z" },
1344
+ { url = "https://files.pythonhosted.org/packages/31/26/ef168b184a25701f9995e8fb7e503fafd7a99c1c77cda1bc1a26ea2ed486/sqlalchemy-2.0.50-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c206aec519a2e7bd08abbfb33436e325fd22c632d9c21a9047e376ce241646e", size = 3287069, upload-time = "2026-05-24T20:17:21.942Z" },
1345
+ { url = "https://files.pythonhosted.org/packages/c2/15/765acc2bc693bccc43ca4a95d5b69750da8aaf6db1b5c616536e087f8920/sqlalchemy-2.0.50-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bef4ac756363227ef6402a75fee025a4bc690f92328e825868939b3b3a446a6d", size = 3230453, upload-time = "2026-05-24T20:09:40.398Z" },
1346
+ { url = "https://files.pythonhosted.org/packages/63/61/08e03c3adbf5db0087a0b6816746fec8f3032fb2f7fc899a9bb9b2a48ce4/sqlalchemy-2.0.50-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:96fbee6b19c19cd1556c8bf9419447cf2ec149ffcab7ab64348c23e54ef8547f", size = 3252413, upload-time = "2026-05-24T20:17:24.067Z" },
1347
+ { url = "https://files.pythonhosted.org/packages/03/0c/370a1f2db38436c615e10134c8a37de3688e74084792380695f3f5083860/sqlalchemy-2.0.50-cp314-cp314-win32.whl", hash = "sha256:8f00e3eb43ba30eb1b238ee03a8a62309486d1321eda3328bb611e0340033ad8", size = 2120063, upload-time = "2026-05-24T19:50:11.08Z" },
1348
+ { url = "https://files.pythonhosted.org/packages/7f/a0/fe92bb9817863bc13ba093bda931979a26cc2ca69f8e8f26d07add3d7c6f/sqlalchemy-2.0.50-cp314-cp314-win_amd64.whl", hash = "sha256:15708c613cd5005b7dffe1f66ee6a63ee8f5e46799f71c70ebad74178c676a39", size = 2145830, upload-time = "2026-05-24T19:50:12.452Z" },
1349
+ { url = "https://files.pythonhosted.org/packages/cc/ff/e5640a98a0b2f491eb8fde10fb6c773621a2e44340de231fafcc9370f4a9/sqlalchemy-2.0.50-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3699dac4be410e97049a1658e9480da9cde956594aa0f3aebc60b88f21c5ba70", size = 2178435, upload-time = "2026-05-24T19:42:58.889Z" },
1350
+ { url = "https://files.pythonhosted.org/packages/b7/85/337116e186f1236375b5fb70c21cfac98e8e8ab0d3a47be838dc47a59e08/sqlalchemy-2.0.50-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f96233858e3df43932ac11589e22520da6e8aeb624b03fedfeebb0e8ea213086", size = 3566059, upload-time = "2026-05-24T20:01:20.848Z" },
1351
+ { url = "https://files.pythonhosted.org/packages/96/34/bb0e190e161c3c2c24314a65add57218be14a4a9486886b7f5047c1ff7c8/sqlalchemy-2.0.50-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c4e70c46fad30c3bcc6a4708bc0130a3173e11a5b25f0ea4a9d8911b450f1f52", size = 3535366, upload-time = "2026-05-24T20:03:56.768Z" },
1352
+ { url = "https://files.pythonhosted.org/packages/df/5a/a7f759f97e4fd499c5d4e4488c760d5a7fbecf3028b465a04274fcd52384/sqlalchemy-2.0.50-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1918a3cf564d16d95bca7301005f41ab2ad50b07cd3b9da50d3ed986db148d6a", size = 3474879, upload-time = "2026-05-24T20:01:23.058Z" },
1353
+ { url = "https://files.pythonhosted.org/packages/9d/d9/2907ea38eb60687d297bf9c39e5ee58053c87b57fe8a9cae97090cecbf10/sqlalchemy-2.0.50-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b00098cdbdbd38c7be3d568b0c9c3122b8c0ec62b911b57cd5e6e0254d60a76d", size = 3486117, upload-time = "2026-05-24T20:03:59.052Z" },
1354
+ { url = "https://files.pythonhosted.org/packages/f2/e3/5aa06f167559f8c0bdae487e297d23ba548150ab016a3418265d617a4985/sqlalchemy-2.0.50-cp314-cp314t-win32.whl", hash = "sha256:1fbd55a969d7ac44a98e3dec75016074f809fa08f871585ace58dde110d1bf3e", size = 2150823, upload-time = "2026-05-24T20:08:58.644Z" },
1355
+ { url = "https://files.pythonhosted.org/packages/65/9b/112fb8f977582d7489d036e409e3723948bcf5320b3ac465f3c481bbe8f9/sqlalchemy-2.0.50-cp314-cp314t-win_amd64.whl", hash = "sha256:c5c3cdb753a9004183e1ccb634b41611654c989e61bc68617ce878e46d6f1e51", size = 2185794, upload-time = "2026-05-24T20:09:00.319Z" },
1356
+ { url = "https://files.pythonhosted.org/packages/d0/10/f7220e9b784d295d241c86ed99aeb537f92afcd469a64861f2717e9bb077/sqlalchemy-2.0.50-py3-none-any.whl", hash = "sha256:92064363517a3ff8212b5a93b8c62876579d8dfd1ca5b561335f30152d884fa9", size = 1943861, upload-time = "2026-05-24T19:59:01.119Z" },
1356
1357
  ]
1357
1358
 
1358
1359
  [package.optional-dependencies]