cloud-sql-python-connector 1.12.0__py2.py3-none-any.whl → 1.13.0__py2.py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloud-sql-python-connector
3
- Version: 1.12.0
3
+ Version: 1.13.0
4
4
  Summary: The Cloud SQL Python Connector is a library that can be used alongside a database driver to allow users with sufficient permissions to connect to a Cloud SQL database without having to manually allowlist IPs or manage SSL certificates.
5
5
  Home-page: https://github.com/GoogleCloudPlatform/cloud-sql-python-connector
6
6
  Author: Google LLC
@@ -11,12 +11,12 @@ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 3.8
15
14
  Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
19
- Requires-Python: >=3.8
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.9
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: aiofiles
@@ -1,8 +1,8 @@
1
1
  google/cloud/sql/connector/__init__.py,sha256=x8ui7u3gMlMI-LLJkKTtUU9yvzZvQkTJ-yzr2FH4VTU,983
2
2
  google/cloud/sql/connector/asyncpg.py,sha256=c4lAlvEgGf_eBq0G8MVNPRAJQQvo6DcwybiXDW36qkU,1838
3
- google/cloud/sql/connector/client.py,sha256=wGO6ESxWWYT5qZ-Utg_qh-Rtl_4k5tIjoD-ILcP4REQ,11481
3
+ google/cloud/sql/connector/client.py,sha256=dqUYJdUdusV_s2Xs0uWFmKqqoOU4mpHkrgl0qqbx9Vw,11713
4
4
  google/cloud/sql/connector/connection_info.py,sha256=exxhtb0-rk8J3OIotf8drEPMx8pke17hAX_Mbt7gOts,4336
5
- google/cloud/sql/connector/connector.py,sha256=4BeJAZNBg_2vbF7XtJvsESKXW7-hM1pyyBu5NIWGbHk,21429
5
+ google/cloud/sql/connector/connector.py,sha256=NWyuwUoAsCuPxxzjB9OiD19tD1LdcQtqfbxJOLlS5-A,20731
6
6
  google/cloud/sql/connector/enums.py,sha256=44tfMm8D_t0ls6GfKwiQ6YkslWM21PZR40RhJPWntkc,2882
7
7
  google/cloud/sql/connector/exceptions.py,sha256=OVenqBkkn98xFeytHuOXFTWa9R5bCmemBtbSIm8caoM,1665
8
8
  google/cloud/sql/connector/instance.py,sha256=EySszNNHMFjAFskf6-G6Upikvb-tYjEwXx9A_OJBl14,10136
@@ -14,9 +14,9 @@ google/cloud/sql/connector/pytds.py,sha256=vKJoE7E2P0GrhZojg8bGZkqCMLc8dgKAcXE4e
14
14
  google/cloud/sql/connector/rate_limiter.py,sha256=bPTupfM4f5QRSCmCAWMqjQylEB7bUM-50plVBU3W2CA,2993
15
15
  google/cloud/sql/connector/refresh_utils.py,sha256=CajL-MOcQBBRUkywowdHB3GNOr0WpQn37DXG7dRpkMk,5069
16
16
  google/cloud/sql/connector/utils.py,sha256=nQVZVfEijbO3XEj1oU68cR-u8Nx99rRM2a8aXaygOg0,3534
17
- google/cloud/sql/connector/version.py,sha256=QmuVMbUhLPcMOkkWA-fPpOpI__yRbL45K8wgkam4960,598
18
- cloud_sql_python_connector-1.12.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
19
- cloud_sql_python_connector-1.12.0.dist-info/METADATA,sha256=LZkFfR0wlQVzFYCJgoQ_AlB8EDT3soKmVdPdF66mDTU,25949
20
- cloud_sql_python_connector-1.12.0.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
21
- cloud_sql_python_connector-1.12.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
22
- cloud_sql_python_connector-1.12.0.dist-info/RECORD,,
17
+ google/cloud/sql/connector/version.py,sha256=EWwYfhVJ-gfn9Us5uJphJ-6hyY5hIvZ1lMkYVSAinqo,598
18
+ cloud_sql_python_connector-1.13.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
19
+ cloud_sql_python_connector-1.13.0.dist-info/METADATA,sha256=4D0iy9DJ08BNblMe2HaliEjMi6Wee_eQVQY_JT7nb4o,25950
20
+ cloud_sql_python_connector-1.13.0.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
21
+ cloud_sql_python_connector-1.13.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
22
+ cloud_sql_python_connector-1.13.0.dist-info/RECORD,,
@@ -141,10 +141,13 @@ class CloudSQLClient:
141
141
  if "ipAddresses" in ret_dict
142
142
  else {}
143
143
  )
144
- # Remove trailing period from PSC DNS name.
145
- psc_dns = ret_dict.get("dnsName")
146
- if psc_dns:
147
- ip_addresses["PSC"] = psc_dns.rstrip(".")
144
+ # resolve dnsName into IP address for PSC
145
+ # Note that we have to check for PSC enablement also because CAS
146
+ # instances also set the dnsName field.
147
+ # Remove trailing period from DNS name. Required for SSL in Python
148
+ dns_name = ret_dict.get("dnsName", "").rstrip(".")
149
+ if dns_name and ret_dict.get("pscEnabled"):
150
+ ip_addresses["PSC"] = dns_name
148
151
 
149
152
  return {
150
153
  "ip_addresses": ip_addresses,
@@ -21,7 +21,7 @@ from functools import partial
21
21
  import logging
22
22
  from threading import Thread
23
23
  from types import TracebackType
24
- from typing import Any, Dict, Optional, Type, Union
24
+ from typing import Any, Dict, Optional, Tuple, Type, Union
25
25
 
26
26
  import google.auth
27
27
  from google.auth.credentials import Credentials
@@ -32,7 +32,6 @@ from google.cloud.sql.connector.client import CloudSQLClient
32
32
  from google.cloud.sql.connector.enums import DriverMapping
33
33
  from google.cloud.sql.connector.enums import IPTypes
34
34
  from google.cloud.sql.connector.enums import RefreshStrategy
35
- from google.cloud.sql.connector.exceptions import ConnectorLoopError
36
35
  from google.cloud.sql.connector.instance import RefreshAheadCache
37
36
  from google.cloud.sql.connector.lazy import LazyRefreshCache
38
37
  import google.cloud.sql.connector.pg8000 as pg8000
@@ -132,7 +131,11 @@ class Connector:
132
131
  asyncio.run_coroutine_threadsafe(generate_keys(), self._loop),
133
132
  loop=self._loop,
134
133
  )
135
- self._cache: Dict[str, Union[RefreshAheadCache, LazyRefreshCache]] = {}
134
+ # initialize dict to store caches, key is a tuple consisting of instance
135
+ # connection name string and enable_iam_auth boolean flag
136
+ self._cache: Dict[
137
+ Tuple[str, bool], Union[RefreshAheadCache, LazyRefreshCache]
138
+ ] = {}
136
139
  self._client: Optional[CloudSQLClient] = None
137
140
 
138
141
  # initialize credentials
@@ -208,27 +211,16 @@ class Connector:
208
211
 
209
212
  Returns:
210
213
  A DB-API connection to the specified Cloud SQL instance.
211
-
212
- Raises:
213
- ConnectorLoopError: Event loop for background refresh is running in
214
- current thread. Error instead of hanging indefinitely.
215
214
  """
216
- try:
217
- # check if event loop is running in current thread
218
- if self._loop == asyncio.get_running_loop():
219
- raise ConnectorLoopError(
220
- "Connector event loop is running in current thread!"
221
- "Event loop must be attached to a different thread to prevent blocking code!"
222
- )
223
- # asyncio.get_running_loop will throw RunTimeError if no running loop is present
224
- except RuntimeError:
225
- pass
226
215
 
227
- # if event loop is not in current thread, proceed with connection
228
- connect_task = asyncio.run_coroutine_threadsafe(
229
- self.connect_async(instance_connection_string, driver, **kwargs), self._loop
216
+ # connect runs sync database connections on background thread.
217
+ # Async database connections should call 'connect_async' directly to
218
+ # avoid hanging indefinitely.
219
+ connect_future = asyncio.run_coroutine_threadsafe(
220
+ self.connect_async(instance_connection_string, driver, **kwargs),
221
+ self._loop,
230
222
  )
231
- return connect_task.result()
223
+ return connect_future.result()
232
224
 
233
225
  async def connect_async(
234
226
  self, instance_connection_string: str, driver: str, **kwargs: Any
@@ -274,15 +266,8 @@ class Connector:
274
266
  driver=driver,
275
267
  )
276
268
  enable_iam_auth = kwargs.pop("enable_iam_auth", self._enable_iam_auth)
277
- if instance_connection_string in self._cache:
278
- cache = self._cache[instance_connection_string]
279
- if enable_iam_auth != cache._enable_iam_auth:
280
- raise ValueError(
281
- f"connect() called with 'enable_iam_auth={enable_iam_auth}', "
282
- f"but previously used 'enable_iam_auth={cache._enable_iam_auth}'. "
283
- "If you require both for your use case, please use a new "
284
- "connector.Connector object."
285
- )
269
+ if (instance_connection_string, enable_iam_auth) in self._cache:
270
+ cache = self._cache[(instance_connection_string, enable_iam_auth)]
286
271
  else:
287
272
  if self._refresh_strategy == RefreshStrategy.LAZY:
288
273
  logger.debug(
@@ -309,7 +294,7 @@ class Connector:
309
294
  logger.debug(
310
295
  f"['{instance_connection_string}']: Connection info added to cache"
311
296
  )
312
- self._cache[instance_connection_string] = cache
297
+ self._cache[(instance_connection_string, enable_iam_auth)] = cache
313
298
 
314
299
  connect_func = {
315
300
  "pymysql": pymysql.connect,
@@ -345,7 +330,7 @@ class Connector:
345
330
  except Exception:
346
331
  # with an error from Cloud SQL Admin API call or IP type, invalidate
347
332
  # the cache and re-raise the error
348
- await self._remove_cached(instance_connection_string)
333
+ await self._remove_cached(instance_connection_string, enable_iam_auth)
349
334
  raise
350
335
  logger.debug(
351
336
  f"['{instance_connection_string}']: Connecting to {ip_address}:3307"
@@ -382,7 +367,9 @@ class Connector:
382
367
  await cache.force_refresh()
383
368
  raise
384
369
 
385
- async def _remove_cached(self, instance_connection_string: str) -> None:
370
+ async def _remove_cached(
371
+ self, instance_connection_string: str, enable_iam_auth: bool
372
+ ) -> None:
386
373
  """Stops all background refreshes and deletes the connection
387
374
  info cache from the map of caches.
388
375
  """
@@ -390,7 +377,7 @@ class Connector:
390
377
  f"['{instance_connection_string}']: Removing connection info from cache"
391
378
  )
392
379
  # remove cache from stored caches and close it
393
- cache = self._cache.pop(instance_connection_string)
380
+ cache = self._cache.pop((instance_connection_string, enable_iam_auth))
394
381
  await cache.close()
395
382
 
396
383
  def __enter__(self) -> Any:
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "1.12.0"
15
+ __version__ = "1.13.0"