cloud-sql-python-connector 1.16.0__tar.gz → 1.18.2__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 (32) hide show
  1. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/PKG-INFO +111 -135
  2. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/README.md +99 -126
  3. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/cloud_sql_python_connector.egg-info/PKG-INFO +111 -135
  4. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/cloud_sql_python_connector.egg-info/SOURCES.txt +2 -3
  5. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/__init__.py +1 -1
  6. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/asyncpg.py +14 -13
  7. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/client.py +42 -38
  8. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/connection_info.py +22 -0
  9. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/connection_name.py +14 -0
  10. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/connector.py +75 -17
  11. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/exceptions.py +7 -0
  12. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/instance.py +12 -1
  13. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/lazy.py +13 -2
  14. cloud_sql_python_connector-1.18.2/google/cloud/sql/connector/monitored_cache.py +146 -0
  15. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/pg8000.py +12 -19
  16. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/pymysql.py +11 -17
  17. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/pytds.py +11 -18
  18. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/rate_limiter.py +9 -17
  19. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/refresh_utils.py +13 -11
  20. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/resolver.py +12 -3
  21. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/utils.py +6 -8
  22. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/version.py +1 -1
  23. cloud_sql_python_connector-1.18.2/pyproject.toml +96 -0
  24. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/setup.cfg +0 -3
  25. cloud_sql_python_connector-1.16.0/cloud_sql_python_connector.egg-info/not-zip-safe +0 -1
  26. cloud_sql_python_connector-1.16.0/setup.py +0 -90
  27. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/LICENSE +0 -0
  28. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/cloud_sql_python_connector.egg-info/dependency_links.txt +0 -0
  29. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/cloud_sql_python_connector.egg-info/requires.txt +0 -0
  30. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/cloud_sql_python_connector.egg-info/top_level.txt +0 -0
  31. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/enums.py +0 -0
  32. {cloud_sql_python_connector-1.16.0 → cloud_sql_python_connector-1.18.2}/google/cloud/sql/connector/py.typed +0 -0
@@ -1,21 +1,23 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: cloud-sql-python-connector
3
- Version: 1.16.0
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
- Home-page: https://github.com/GoogleCloudPlatform/cloud-sql-python-connector
6
- Author: Google LLC
7
- Author-email: googleapis-packages@google.com
8
- License: Apache 2.0
9
- Platform: Posix; MacOS X; Windows
3
+ Version: 1.18.2
4
+ Summary: Google Cloud SQL Python Connector library
5
+ Author-email: Google LLC <googleapis-packages@google.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/GoogleCloudPlatform/cloud-sql-python-connector
8
+ Project-URL: Repository, https://github.com/GoogleCloudPlatform/cloud-sql-python-connector.git
9
+ Project-URL: Issues, https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/issues
10
+ Project-URL: Changelog, https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/blob/main/CHANGELOG.md
10
11
  Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
14
15
  Classifier: Programming Language :: Python :: 3.9
15
16
  Classifier: Programming Language :: Python :: 3.10
16
17
  Classifier: Programming Language :: Python :: 3.11
17
18
  Classifier: Programming Language :: Python :: 3.12
18
19
  Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Operating System :: OS Independent
19
21
  Requires-Python: >=3.9
20
22
  Description-Content-Type: text/markdown
21
23
  License-File: LICENSE
@@ -33,6 +35,7 @@ Provides-Extra: pytds
33
35
  Requires-Dist: python-tds>=1.15.0; extra == "pytds"
34
36
  Provides-Extra: asyncpg
35
37
  Requires-Dist: asyncpg>=0.30.0; extra == "asyncpg"
38
+ Dynamic: license-file
36
39
 
37
40
  <p align="center">
38
41
  <a href="https://cloud.google.com/blog/topics/developers-practitioners/how-connect-cloud-sql-using-python-easy-way">
@@ -162,21 +165,16 @@ import sqlalchemy
162
165
  # initialize Connector object
163
166
  connector = Connector()
164
167
 
165
- # function to return the database connection
166
- def getconn() -> pymysql.connections.Connection:
167
- conn: pymysql.connections.Connection = connector.connect(
168
+ # initialize SQLAlchemy connection pool with Connector
169
+ pool = sqlalchemy.create_engine(
170
+ "mysql+pymysql://",
171
+ creator=lambda: connector.connect(
168
172
  "project:region:instance",
169
173
  "pymysql",
170
174
  user="my-user",
171
175
  password="my-password",
172
176
  db="my-db-name"
173
- )
174
- return conn
175
-
176
- # create connection pool
177
- pool = sqlalchemy.create_engine(
178
- "mysql+pymysql://",
179
- creator=getconn,
177
+ ),
180
178
  )
181
179
  ```
182
180
 
@@ -243,33 +241,21 @@ Connector as a context manager:
243
241
 
244
242
  ```python
245
243
  from google.cloud.sql.connector import Connector
246
- import pymysql
247
244
  import sqlalchemy
248
245
 
249
- # helper function to return SQLAlchemy connection pool
250
- def init_connection_pool(connector: Connector) -> sqlalchemy.engine.Engine:
251
- # function used to generate database connection
252
- def getconn() -> pymysql.connections.Connection:
253
- conn = connector.connect(
246
+ # initialize Cloud SQL Python Connector as context manager
247
+ with Connector() as connector:
248
+ # initialize SQLAlchemy connection pool with Connector
249
+ pool = sqlalchemy.create_engine(
250
+ "mysql+pymysql://",
251
+ creator=lambda: connector.connect(
254
252
  "project:region:instance",
255
253
  "pymysql",
256
254
  user="my-user",
257
255
  password="my-password",
258
256
  db="my-db-name"
259
- )
260
- return conn
261
-
262
- # create connection pool
263
- pool = sqlalchemy.create_engine(
264
- "mysql+pymysql://",
265
- creator=getconn,
257
+ ),
266
258
  )
267
- return pool
268
-
269
- # initialize Cloud SQL Python Connector as context manager
270
- with Connector() as connector:
271
- # initialize connection pool
272
- pool = init_connection_pool(connector)
273
259
  # insert statement
274
260
  insert_stmt = sqlalchemy.text(
275
261
  "INSERT INTO my_table (id, title) VALUES (:id, :title)",
@@ -437,33 +423,60 @@ from google.cloud.sql.connector import Connector, DnsResolver
437
423
  import pymysql
438
424
  import sqlalchemy
439
425
 
440
- # helper function to return SQLAlchemy connection pool
441
- def init_connection_pool(connector: Connector) -> sqlalchemy.engine.Engine:
442
- # function used to generate database connection
443
- def getconn() -> pymysql.connections.Connection:
444
- conn = connector.connect(
426
+ # initialize Cloud SQL Python Connector with `resolver=DnsResolver`
427
+ with Connector(resolver=DnsResolver) as connector:
428
+ # initialize SQLAlchemy connection pool with Connector
429
+ pool = sqlalchemy.create_engine(
430
+ "mysql+pymysql://",
431
+ creator=lambda: connector.connect(
445
432
  "prod-db.mycompany.example.com", # using DNS name
446
433
  "pymysql",
447
434
  user="my-user",
448
435
  password="my-password",
449
436
  db="my-db-name"
450
- )
451
- return conn
452
-
453
- # create connection pool
454
- pool = sqlalchemy.create_engine(
455
- "mysql+pymysql://",
456
- creator=getconn,
437
+ ),
457
438
  )
458
- return pool
459
-
460
- # initialize Cloud SQL Python Connector with `resolver=DnsResolver`
461
- with Connector(resolver=DnsResolver) as connector:
462
- # initialize connection pool
463
- pool = init_connection_pool(connector)
464
439
  # ... use SQLAlchemy engine normally
465
440
  ```
466
441
 
442
+ ### Automatic failover using DNS domain names
443
+
444
+ > [!NOTE]
445
+ >
446
+ > Usage of the `asyncpg` driver does not currently support automatic failover.
447
+
448
+ When the connector is configured using a domain name, the connector will
449
+ periodically check if the DNS record for an instance changes. When the connector
450
+ detects that the domain name refers to a different instance, the connector will
451
+ close all open connections to the old instance. Subsequent connection attempts
452
+ will be directed to the new instance.
453
+
454
+ For example: suppose application is configured to connect using the
455
+ domain name `prod-db.mycompany.example.com`. Initially the private DNS
456
+ zone has a TXT record with the value `my-project:region:my-instance`. The
457
+ application establishes connections to the `my-project:region:my-instance`
458
+ Cloud SQL instance.
459
+
460
+ Then, to reconfigure the application to use a different database
461
+ instance, change the value of the `prod-db.mycompany.example.com` DNS record
462
+ from `my-project:region:my-instance` to `my-project:other-region:my-instance-2`
463
+
464
+ The connector inside the application detects the change to this
465
+ DNS record. Now, when the application connects to its database using the
466
+ domain name `prod-db.mycompany.example.com`, it will connect to the
467
+ `my-project:other-region:my-instance-2` Cloud SQL instance.
468
+
469
+ The connector will automatically close all existing connections to
470
+ `my-project:region:my-instance`. This will force the connection pools to
471
+ establish new connections. Also, it may cause database queries in progress
472
+ to fail.
473
+
474
+ The connector will poll for changes to the DNS name every 30 seconds by default.
475
+ You may configure the frequency of the connections using the Connector's
476
+ `failover_period` argument (i.e. `Connector(failover_period=60`). When this is
477
+ set to 0, the connector will disable polling and only check if the DNS record
478
+ changed when it is creating a new connection.
479
+
467
480
  ### Using the Python Connector with Python Web Frameworks
468
481
 
469
482
  The Python Connector can be used alongside popular Python web frameworks such
@@ -499,9 +512,12 @@ from google.cloud.sql.connector import Connector
499
512
  # initialize Python Connector object
500
513
  connector = Connector()
501
514
 
502
- # Python Connector database connection function
503
- def getconn():
504
- conn = connector.connect(
515
+ app = Flask(__name__)
516
+
517
+ # configure Flask-SQLAlchemy to use Python Connector
518
+ app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql+pg8000://"
519
+ app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
520
+ "creator": lambda: conn = connector.connect(
505
521
  "project:region:instance-name", # Cloud SQL Instance Connection Name
506
522
  "pg8000",
507
523
  user="my-user",
@@ -509,15 +525,6 @@ def getconn():
509
525
  db="my-database",
510
526
  ip_type="public" # "private" for private IP
511
527
  )
512
- return conn
513
-
514
-
515
- app = Flask(__name__)
516
-
517
- # configure Flask-SQLAlchemy to use Python Connector
518
- app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql+pg8000://"
519
- app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
520
- "creator": getconn
521
528
  }
522
529
 
523
530
  # initialize the app with the extension
@@ -538,38 +545,27 @@ your web application using [SQLAlchemy ORM](https://docs.sqlalchemy.org/en/14/or
538
545
  through the following:
539
546
 
540
547
  ```python
541
- from sqlalchemy import create_engine
542
- from sqlalchemy.engine import Engine
548
+ import sqlalchemy
543
549
  from sqlalchemy.ext.declarative import declarative_base
544
550
  from sqlalchemy.orm import sessionmaker
545
551
  from google.cloud.sql.connector import Connector
546
552
 
547
- # helper function to return SQLAlchemy connection pool
548
- def init_connection_pool(connector: Connector) -> Engine:
549
- # Python Connector database connection function
550
- def getconn():
551
- conn = connector.connect(
552
- "project:region:instance-name", # Cloud SQL Instance Connection Name
553
- "pg8000",
554
- user="my-user",
555
- password="my-password",
556
- db="my-database",
557
- ip_type="public" # "private" for private IP
558
- )
559
- return conn
560
-
561
- SQLALCHEMY_DATABASE_URL = "postgresql+pg8000://"
562
-
563
- engine = create_engine(
564
- SQLALCHEMY_DATABASE_URL , creator=getconn
565
- )
566
- return engine
567
553
 
568
554
  # initialize Cloud SQL Python Connector
569
555
  connector = Connector()
570
556
 
571
557
  # create connection pool engine
572
- engine = init_connection_pool(connector)
558
+ engine = sqlalchemy.create_engine(
559
+ "postgresql+pg8000://",
560
+ creator=lambda: connector.connect(
561
+ "project:region:instance-name", # Cloud SQL Instance Connection Name
562
+ "pg8000",
563
+ user="my-user",
564
+ password="my-password",
565
+ db="my-database",
566
+ ip_type="public" # "private" for private IP
567
+ ),
568
+ )
573
569
 
574
570
  # create SQLAlchemy ORM session
575
571
  SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@@ -638,40 +634,29 @@ async def main():
638
634
  #### SQLAlchemy Async Engine
639
635
 
640
636
  ```python
641
- import asyncpg
642
-
643
637
  import sqlalchemy
644
638
  from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
645
639
 
646
640
  from google.cloud.sql.connector import Connector, create_async_connector
647
641
 
648
- async def init_connection_pool(connector: Connector) -> AsyncEngine:
649
- # creation function to generate asyncpg connections as 'async_creator' arg
650
- async def getconn() -> asyncpg.Connection:
651
- conn: asyncpg.Connection = await connector.connect_async(
642
+
643
+ async def main():
644
+ # initialize Connector object for connections to Cloud SQL
645
+ connector = await create_async_connector()
646
+
647
+ # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
648
+ # 'async_creator' argument to 'create_async_engine'
649
+ pool = create_async_engine(
650
+ "postgresql+asyncpg://",
651
+ async_creator=lambda: connector.connect_async(
652
652
  "project:region:instance", # Cloud SQL instance connection name
653
653
  "asyncpg",
654
654
  user="my-user",
655
655
  password="my-password",
656
656
  db="my-db-name"
657
657
  # ... additional database driver args
658
- )
659
- return conn
660
-
661
- # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
662
- # 'async_creator' argument to 'create_async_engine'
663
- pool = create_async_engine(
664
- "postgresql+asyncpg://",
665
- async_creator=getconn,
658
+ ),
666
659
  )
667
- return pool
668
-
669
- async def main():
670
- # initialize Connector object for connections to Cloud SQL
671
- connector = await create_async_connector()
672
-
673
- # initialize connection pool
674
- pool = await init_connection_pool(connector)
675
660
 
676
661
  # example query
677
662
  async with pool.connect() as conn:
@@ -742,33 +727,24 @@ from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
742
727
 
743
728
  from google.cloud.sql.connector import Connector
744
729
 
745
- async def init_connection_pool(connector: Connector) -> AsyncEngine:
746
- # creation function to generate asyncpg connections as 'async_creator' arg
747
- async def getconn() -> asyncpg.Connection:
748
- conn: asyncpg.Connection = await connector.connect_async(
749
- "project:region:instance", # Cloud SQL instance connection name
750
- "asyncpg",
751
- user="my-user",
752
- password="my-password",
753
- db="my-db-name"
754
- # ... additional database driver args
755
- )
756
- return conn
757
-
758
- # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
759
- # 'async_creator' argument to 'create_async_engine'
760
- pool = create_async_engine(
761
- "postgresql+asyncpg://",
762
- async_creator=getconn,
763
- )
764
- return pool
765
730
 
766
731
  async def main():
767
732
  # initialize Connector object for connections to Cloud SQL
768
733
  loop = asyncio.get_running_loop()
769
734
  async with Connector(loop=loop) as connector:
770
- # initialize connection pool
771
- pool = await init_connection_pool(connector)
735
+ # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
736
+ # 'async_creator' argument to 'create_async_engine'
737
+ pool = create_async_engine(
738
+ "postgresql+asyncpg://",
739
+ async_creator=lambda: connector.connect_async(
740
+ "project:region:instance", # Cloud SQL instance connection name
741
+ "asyncpg",
742
+ user="my-user",
743
+ password="my-password",
744
+ db="my-db-name"
745
+ # ... additional database driver args
746
+ ),
747
+ )
772
748
 
773
749
  # example query
774
750
  async with pool.connect() as conn: