cloud-sql-python-connector 1.22.0__tar.gz → 1.24.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 (35) hide show
  1. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/PKG-INFO +89 -9
  2. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/README.md +84 -2
  3. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/cloud_sql_python_connector.egg-info/PKG-INFO +89 -9
  4. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/cloud_sql_python_connector.egg-info/SOURCES.txt +2 -0
  5. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/cloud_sql_python_connector.egg-info/requires.txt +1 -3
  6. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/client.py +15 -3
  7. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/connection_info.py +12 -1
  8. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/connector.py +445 -134
  9. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/enums.py +3 -0
  10. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/exceptions.py +33 -0
  11. cloud_sql_python_connector-1.24.0/google/cloud/sql/connector/instance.py +461 -0
  12. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/lazy.py +47 -3
  13. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/monitored_cache.py +14 -8
  14. cloud_sql_python_connector-1.24.0/google/cloud/sql/connector/postgres_connection.py +235 -0
  15. cloud_sql_python_connector-1.24.0/google/cloud/sql/connector/psycopg.py +323 -0
  16. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/refresh_utils.py +4 -3
  17. cloud_sql_python_connector-1.24.0/google/cloud/sql/connector/sqldata_client.py +654 -0
  18. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/utils.py +1 -1
  19. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/version.py +1 -1
  20. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/pyproject.toml +20 -7
  21. cloud_sql_python_connector-1.22.0/google/cloud/sql/connector/instance.py +0 -225
  22. cloud_sql_python_connector-1.22.0/google/cloud/sql/connector/psycopg.py +0 -235
  23. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/LICENSE +0 -0
  24. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/cloud_sql_python_connector.egg-info/dependency_links.txt +0 -0
  25. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/cloud_sql_python_connector.egg-info/top_level.txt +0 -0
  26. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/__init__.py +0 -0
  27. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/asyncpg.py +0 -0
  28. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/connection_name.py +0 -0
  29. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/pg8000.py +0 -0
  30. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/py.typed +0 -0
  31. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/pymysql.py +0 -0
  32. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/pytds.py +0 -0
  33. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/rate_limiter.py +0 -0
  34. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/google/cloud/sql/connector/resolver.py +0 -0
  35. {cloud_sql_python_connector-1.22.0 → cloud_sql_python_connector-1.24.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloud-sql-python-connector
3
- Version: 1.22.0
3
+ Version: 1.24.0
4
4
  Summary: Google Cloud SQL Python Connector library
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License-Expression: Apache-2.0
@@ -12,13 +12,13 @@ Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
- Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
19
17
  Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3.15
20
20
  Classifier: Operating System :: OS Independent
21
- Requires-Python: >=3.9
21
+ Requires-Python: >=3.11
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: aiohttp
@@ -26,9 +26,7 @@ Requires-Dist: cryptography>=42.0.0
26
26
  Requires-Dist: dnspython>=2.0.0
27
27
  Requires-Dist: Requests
28
28
  Requires-Dist: google-auth>=2.28.0
29
- Requires-Dist: grpcio
30
- Requires-Dist: protobuf
31
- Requires-Dist: googleapis-common-protos
29
+ Requires-Dist: google-cloud-sql>=0.1.1
32
30
  Provides-Extra: pymysql
33
31
  Requires-Dist: PyMySQL>=1.1.0; extra == "pymysql"
34
32
  Provides-Extra: pg8000
@@ -244,7 +242,7 @@ from google.cloud.sql.connector import Connector
244
242
 
245
243
  # Note: all parameters below are optional
246
244
  connector = Connector(
247
- ip_type="public", # can also be "private" or "psc"
245
+ ip_type="public", # can also be "private", "psc", or "sql_data"
248
246
  enable_iam_auth=False,
249
247
  timeout=30,
250
248
  credentials=custom_creds, # google.auth.credentials.Credentials
@@ -322,7 +320,11 @@ with, set the `ip_type` keyword argument when initializing a `Connector()` or wh
322
320
  calling `connector.connect()`.
323
321
 
324
322
  Possible values for `ip_type` are `"public"` (default value),
325
- `"private"`, and `"psc"`.
323
+ `"private"`, `"psc"`, and `"sql_data"`.
324
+
325
+ > [!NOTE]
326
+ >
327
+ > Usage of the `asyncpg` driver does not currently support `ip_type="sql_data"` (`IPTypes.SQL_DATA`).
326
328
 
327
329
  Example:
328
330
 
@@ -788,6 +790,84 @@ async def main():
788
790
  await pool.dispose()
789
791
  ```
790
792
 
793
+ ### Post-Quantum Cryptography (PQC)
794
+
795
+ The Cloud SQL Python Connector establishes mTLS connections over TLS 1.3 using
796
+ Python's standard `ssl` module without restricting key-exchange groups. When
797
+ Python's `ssl` module is linked against **OpenSSL 3.5 or later**, TLS 1.3
798
+ connections automatically offer and negotiate the hybrid post-quantum key
799
+ exchange group **`X25519MLKEM768`** (ML-KEM-768 combined with X25519) whenever
800
+ the Cloud SQL instance supports it. No code changes or connector configuration
801
+ are required.
802
+
803
+ #### Checking your OpenSSL version
804
+
805
+ Post-quantum TLS key exchange depends on the OpenSSL library linked into your
806
+ Python runtime's `ssl` module (not the Python language version or the
807
+ `cryptography` package version alone). Run the following command to check which
808
+ OpenSSL version your Python interpreter uses:
809
+
810
+ ```sh
811
+ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
812
+ ```
813
+
814
+ - **OpenSSL 3.5.0 or higher** (for example, `python:3.13-trixie` / Debian 13
815
+ "Trixie" container images; check your runtime with the one-liner above):
816
+ `X25519MLKEM768` is enabled by default on TLS 1.3 connections.
817
+ - **OpenSSL earlier than 3.5.0** (for example, Ubuntu 24.04 LTS, which ships
818
+ system OpenSSL 3.0.x): TLS 1.3 connections continue to use classical elliptic
819
+ curve Diffie-Hellman (such as `X25519` or `P-256`).
820
+
821
+ > [!NOTE]
822
+ >
823
+ > Connections configured with `ip_type="sql_data"` (`IPTypes.SQL_DATA`) stream
824
+ > over gRPC (`grpcio`), which uses its bundled BoringSSL (supporting
825
+ > `X25519MLKEM768` independently of Python's `ssl` module and `OPENSSL_CONF`),
826
+ > whereas its direct-TLS fallback path uses `create_ssl_context()` and Python's
827
+ > linked OpenSSL library as described above.
828
+
829
+ #### Backwards compatibility
830
+
831
+ Hybrid post-quantum key exchange is backwards-compatible. On OpenSSL 3.5+,
832
+ Python's `ssl` module advertises both hybrid (`X25519MLKEM768`) and classical
833
+ (`X25519`, `secp256r1`, etc.) groups in the TLS 1.3 `ClientHello`. If either the
834
+ client runtime (OpenSSL `< 3.5`) or the Cloud SQL instance only supports
835
+ classical groups, the TLS 1.3 handshake automatically falls back to classical
836
+ ECDHE without error.
837
+
838
+ #### Opting out
839
+
840
+ If you need to disable post-quantum key exchange on an OpenSSL 3.5+ client (for
841
+ example, to troubleshoot a network middlebox sensitive to larger TLS
842
+ `ClientHello` records), configure OpenSSL's `Groups` list via an OpenSSL
843
+ configuration file (`OPENSSL_CONF`) to advertise only classical curves.
844
+
845
+ > [!WARNING]
846
+ >
847
+ > Setting `OPENSSL_CONF` replaces the system default OpenSSL configuration for
848
+ > the entire Python process. It affects **all** TLS connections made by the
849
+ > process (not just Cloud SQL connections), and starting from a minimal file
850
+ > omits distribution defaults (such as Debian's `MinProtocol` or
851
+ > `CipherString`). Copy your system's `openssl.cnf` (check `openssl version -d`,
852
+ > typically `/etc/ssl/openssl.cnf`) and add `Groups = X25519:P-256:P-384` under
853
+ > its `[system_default_sect]` section rather than using a bare file from
854
+ > scratch.
855
+
856
+ For example, after copying `/etc/ssl/openssl.cnf`, ensure its
857
+ `[system_default_sect]` (referenced via `ssl_conf` -> `system_default`) sets
858
+ `Groups`:
859
+
860
+ ```ini
861
+ [system_default_sect]
862
+ Groups = X25519:P-256:P-384
863
+ ```
864
+
865
+ Then point `OPENSSL_CONF` to your modified copy when starting your application:
866
+
867
+ ```sh
868
+ OPENSSL_CONF=/path/to/openssl.cnf python3 app.py
869
+ ```
870
+
791
871
  ### Debug Logging
792
872
 
793
873
  The Cloud SQL Python Connector uses the standard [Python logging module][python-logging]
@@ -201,7 +201,7 @@ from google.cloud.sql.connector import Connector
201
201
 
202
202
  # Note: all parameters below are optional
203
203
  connector = Connector(
204
- ip_type="public", # can also be "private" or "psc"
204
+ ip_type="public", # can also be "private", "psc", or "sql_data"
205
205
  enable_iam_auth=False,
206
206
  timeout=30,
207
207
  credentials=custom_creds, # google.auth.credentials.Credentials
@@ -279,7 +279,11 @@ with, set the `ip_type` keyword argument when initializing a `Connector()` or wh
279
279
  calling `connector.connect()`.
280
280
 
281
281
  Possible values for `ip_type` are `"public"` (default value),
282
- `"private"`, and `"psc"`.
282
+ `"private"`, `"psc"`, and `"sql_data"`.
283
+
284
+ > [!NOTE]
285
+ >
286
+ > Usage of the `asyncpg` driver does not currently support `ip_type="sql_data"` (`IPTypes.SQL_DATA`).
283
287
 
284
288
  Example:
285
289
 
@@ -745,6 +749,84 @@ async def main():
745
749
  await pool.dispose()
746
750
  ```
747
751
 
752
+ ### Post-Quantum Cryptography (PQC)
753
+
754
+ The Cloud SQL Python Connector establishes mTLS connections over TLS 1.3 using
755
+ Python's standard `ssl` module without restricting key-exchange groups. When
756
+ Python's `ssl` module is linked against **OpenSSL 3.5 or later**, TLS 1.3
757
+ connections automatically offer and negotiate the hybrid post-quantum key
758
+ exchange group **`X25519MLKEM768`** (ML-KEM-768 combined with X25519) whenever
759
+ the Cloud SQL instance supports it. No code changes or connector configuration
760
+ are required.
761
+
762
+ #### Checking your OpenSSL version
763
+
764
+ Post-quantum TLS key exchange depends on the OpenSSL library linked into your
765
+ Python runtime's `ssl` module (not the Python language version or the
766
+ `cryptography` package version alone). Run the following command to check which
767
+ OpenSSL version your Python interpreter uses:
768
+
769
+ ```sh
770
+ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
771
+ ```
772
+
773
+ - **OpenSSL 3.5.0 or higher** (for example, `python:3.13-trixie` / Debian 13
774
+ "Trixie" container images; check your runtime with the one-liner above):
775
+ `X25519MLKEM768` is enabled by default on TLS 1.3 connections.
776
+ - **OpenSSL earlier than 3.5.0** (for example, Ubuntu 24.04 LTS, which ships
777
+ system OpenSSL 3.0.x): TLS 1.3 connections continue to use classical elliptic
778
+ curve Diffie-Hellman (such as `X25519` or `P-256`).
779
+
780
+ > [!NOTE]
781
+ >
782
+ > Connections configured with `ip_type="sql_data"` (`IPTypes.SQL_DATA`) stream
783
+ > over gRPC (`grpcio`), which uses its bundled BoringSSL (supporting
784
+ > `X25519MLKEM768` independently of Python's `ssl` module and `OPENSSL_CONF`),
785
+ > whereas its direct-TLS fallback path uses `create_ssl_context()` and Python's
786
+ > linked OpenSSL library as described above.
787
+
788
+ #### Backwards compatibility
789
+
790
+ Hybrid post-quantum key exchange is backwards-compatible. On OpenSSL 3.5+,
791
+ Python's `ssl` module advertises both hybrid (`X25519MLKEM768`) and classical
792
+ (`X25519`, `secp256r1`, etc.) groups in the TLS 1.3 `ClientHello`. If either the
793
+ client runtime (OpenSSL `< 3.5`) or the Cloud SQL instance only supports
794
+ classical groups, the TLS 1.3 handshake automatically falls back to classical
795
+ ECDHE without error.
796
+
797
+ #### Opting out
798
+
799
+ If you need to disable post-quantum key exchange on an OpenSSL 3.5+ client (for
800
+ example, to troubleshoot a network middlebox sensitive to larger TLS
801
+ `ClientHello` records), configure OpenSSL's `Groups` list via an OpenSSL
802
+ configuration file (`OPENSSL_CONF`) to advertise only classical curves.
803
+
804
+ > [!WARNING]
805
+ >
806
+ > Setting `OPENSSL_CONF` replaces the system default OpenSSL configuration for
807
+ > the entire Python process. It affects **all** TLS connections made by the
808
+ > process (not just Cloud SQL connections), and starting from a minimal file
809
+ > omits distribution defaults (such as Debian's `MinProtocol` or
810
+ > `CipherString`). Copy your system's `openssl.cnf` (check `openssl version -d`,
811
+ > typically `/etc/ssl/openssl.cnf`) and add `Groups = X25519:P-256:P-384` under
812
+ > its `[system_default_sect]` section rather than using a bare file from
813
+ > scratch.
814
+
815
+ For example, after copying `/etc/ssl/openssl.cnf`, ensure its
816
+ `[system_default_sect]` (referenced via `ssl_conf` -> `system_default`) sets
817
+ `Groups`:
818
+
819
+ ```ini
820
+ [system_default_sect]
821
+ Groups = X25519:P-256:P-384
822
+ ```
823
+
824
+ Then point `OPENSSL_CONF` to your modified copy when starting your application:
825
+
826
+ ```sh
827
+ OPENSSL_CONF=/path/to/openssl.cnf python3 app.py
828
+ ```
829
+
748
830
  ### Debug Logging
749
831
 
750
832
  The Cloud SQL Python Connector uses the standard [Python logging module][python-logging]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloud-sql-python-connector
3
- Version: 1.22.0
3
+ Version: 1.24.0
4
4
  Summary: Google Cloud SQL Python Connector library
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License-Expression: Apache-2.0
@@ -12,13 +12,13 @@ Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
- Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
19
17
  Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3.15
20
20
  Classifier: Operating System :: OS Independent
21
- Requires-Python: >=3.9
21
+ Requires-Python: >=3.11
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: aiohttp
@@ -26,9 +26,7 @@ Requires-Dist: cryptography>=42.0.0
26
26
  Requires-Dist: dnspython>=2.0.0
27
27
  Requires-Dist: Requests
28
28
  Requires-Dist: google-auth>=2.28.0
29
- Requires-Dist: grpcio
30
- Requires-Dist: protobuf
31
- Requires-Dist: googleapis-common-protos
29
+ Requires-Dist: google-cloud-sql>=0.1.1
32
30
  Provides-Extra: pymysql
33
31
  Requires-Dist: PyMySQL>=1.1.0; extra == "pymysql"
34
32
  Provides-Extra: pg8000
@@ -244,7 +242,7 @@ from google.cloud.sql.connector import Connector
244
242
 
245
243
  # Note: all parameters below are optional
246
244
  connector = Connector(
247
- ip_type="public", # can also be "private" or "psc"
245
+ ip_type="public", # can also be "private", "psc", or "sql_data"
248
246
  enable_iam_auth=False,
249
247
  timeout=30,
250
248
  credentials=custom_creds, # google.auth.credentials.Credentials
@@ -322,7 +320,11 @@ with, set the `ip_type` keyword argument when initializing a `Connector()` or wh
322
320
  calling `connector.connect()`.
323
321
 
324
322
  Possible values for `ip_type` are `"public"` (default value),
325
- `"private"`, and `"psc"`.
323
+ `"private"`, `"psc"`, and `"sql_data"`.
324
+
325
+ > [!NOTE]
326
+ >
327
+ > Usage of the `asyncpg` driver does not currently support `ip_type="sql_data"` (`IPTypes.SQL_DATA`).
326
328
 
327
329
  Example:
328
330
 
@@ -788,6 +790,84 @@ async def main():
788
790
  await pool.dispose()
789
791
  ```
790
792
 
793
+ ### Post-Quantum Cryptography (PQC)
794
+
795
+ The Cloud SQL Python Connector establishes mTLS connections over TLS 1.3 using
796
+ Python's standard `ssl` module without restricting key-exchange groups. When
797
+ Python's `ssl` module is linked against **OpenSSL 3.5 or later**, TLS 1.3
798
+ connections automatically offer and negotiate the hybrid post-quantum key
799
+ exchange group **`X25519MLKEM768`** (ML-KEM-768 combined with X25519) whenever
800
+ the Cloud SQL instance supports it. No code changes or connector configuration
801
+ are required.
802
+
803
+ #### Checking your OpenSSL version
804
+
805
+ Post-quantum TLS key exchange depends on the OpenSSL library linked into your
806
+ Python runtime's `ssl` module (not the Python language version or the
807
+ `cryptography` package version alone). Run the following command to check which
808
+ OpenSSL version your Python interpreter uses:
809
+
810
+ ```sh
811
+ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
812
+ ```
813
+
814
+ - **OpenSSL 3.5.0 or higher** (for example, `python:3.13-trixie` / Debian 13
815
+ "Trixie" container images; check your runtime with the one-liner above):
816
+ `X25519MLKEM768` is enabled by default on TLS 1.3 connections.
817
+ - **OpenSSL earlier than 3.5.0** (for example, Ubuntu 24.04 LTS, which ships
818
+ system OpenSSL 3.0.x): TLS 1.3 connections continue to use classical elliptic
819
+ curve Diffie-Hellman (such as `X25519` or `P-256`).
820
+
821
+ > [!NOTE]
822
+ >
823
+ > Connections configured with `ip_type="sql_data"` (`IPTypes.SQL_DATA`) stream
824
+ > over gRPC (`grpcio`), which uses its bundled BoringSSL (supporting
825
+ > `X25519MLKEM768` independently of Python's `ssl` module and `OPENSSL_CONF`),
826
+ > whereas its direct-TLS fallback path uses `create_ssl_context()` and Python's
827
+ > linked OpenSSL library as described above.
828
+
829
+ #### Backwards compatibility
830
+
831
+ Hybrid post-quantum key exchange is backwards-compatible. On OpenSSL 3.5+,
832
+ Python's `ssl` module advertises both hybrid (`X25519MLKEM768`) and classical
833
+ (`X25519`, `secp256r1`, etc.) groups in the TLS 1.3 `ClientHello`. If either the
834
+ client runtime (OpenSSL `< 3.5`) or the Cloud SQL instance only supports
835
+ classical groups, the TLS 1.3 handshake automatically falls back to classical
836
+ ECDHE without error.
837
+
838
+ #### Opting out
839
+
840
+ If you need to disable post-quantum key exchange on an OpenSSL 3.5+ client (for
841
+ example, to troubleshoot a network middlebox sensitive to larger TLS
842
+ `ClientHello` records), configure OpenSSL's `Groups` list via an OpenSSL
843
+ configuration file (`OPENSSL_CONF`) to advertise only classical curves.
844
+
845
+ > [!WARNING]
846
+ >
847
+ > Setting `OPENSSL_CONF` replaces the system default OpenSSL configuration for
848
+ > the entire Python process. It affects **all** TLS connections made by the
849
+ > process (not just Cloud SQL connections), and starting from a minimal file
850
+ > omits distribution defaults (such as Debian's `MinProtocol` or
851
+ > `CipherString`). Copy your system's `openssl.cnf` (check `openssl version -d`,
852
+ > typically `/etc/ssl/openssl.cnf`) and add `Groups = X25519:P-256:P-384` under
853
+ > its `[system_default_sect]` section rather than using a bare file from
854
+ > scratch.
855
+
856
+ For example, after copying `/etc/ssl/openssl.cnf`, ensure its
857
+ `[system_default_sect]` (referenced via `ssl_conf` -> `system_default`) sets
858
+ `Groups`:
859
+
860
+ ```ini
861
+ [system_default_sect]
862
+ Groups = X25519:P-256:P-384
863
+ ```
864
+
865
+ Then point `OPENSSL_CONF` to your modified copy when starting your application:
866
+
867
+ ```sh
868
+ OPENSSL_CONF=/path/to/openssl.cnf python3 app.py
869
+ ```
870
+
791
871
  ### Debug Logging
792
872
 
793
873
  The Cloud SQL Python Connector uses the standard [Python logging module][python-logging]
@@ -18,6 +18,7 @@ google/cloud/sql/connector/instance.py
18
18
  google/cloud/sql/connector/lazy.py
19
19
  google/cloud/sql/connector/monitored_cache.py
20
20
  google/cloud/sql/connector/pg8000.py
21
+ google/cloud/sql/connector/postgres_connection.py
21
22
  google/cloud/sql/connector/psycopg.py
22
23
  google/cloud/sql/connector/py.typed
23
24
  google/cloud/sql/connector/pymysql.py
@@ -25,5 +26,6 @@ google/cloud/sql/connector/pytds.py
25
26
  google/cloud/sql/connector/rate_limiter.py
26
27
  google/cloud/sql/connector/refresh_utils.py
27
28
  google/cloud/sql/connector/resolver.py
29
+ google/cloud/sql/connector/sqldata_client.py
28
30
  google/cloud/sql/connector/utils.py
29
31
  google/cloud/sql/connector/version.py
@@ -3,9 +3,7 @@ cryptography>=42.0.0
3
3
  dnspython>=2.0.0
4
4
  Requests
5
5
  google-auth>=2.28.0
6
- grpcio
7
- protobuf
8
- googleapis-common-protos
6
+ google-cloud-sql>=0.1.1
9
7
 
10
8
  [asyncpg]
11
9
  asyncpg>=0.30.0
@@ -173,9 +173,13 @@ class CloudSQLClient:
173
173
  if psc_dns_names:
174
174
  ip_addresses["PSC"] = psc_dns_names
175
175
 
176
+ server_ca_cert = None
177
+ if "serverCaCert" in ret_dict and "cert" in ret_dict["serverCaCert"]:
178
+ server_ca_cert = ret_dict["serverCaCert"]["cert"]
179
+
176
180
  return {
177
181
  "ip_addresses": ip_addresses,
178
- "server_ca_cert": ret_dict["serverCaCert"]["cert"],
182
+ "server_ca_cert": server_ca_cert,
179
183
  "database_version": ret_dict["databaseVersion"],
180
184
  }
181
185
 
@@ -271,7 +275,15 @@ class CloudSQLClient:
271
275
  finally:
272
276
  resp.raise_for_status()
273
277
 
274
- ephemeral_cert: str = ret_dict["ephemeralCert"]["cert"]
278
+ try:
279
+ ephemeral_cert: str = ret_dict["ephemeralCert"]["cert"]
280
+ except KeyError as e:
281
+ logger.error(
282
+ "KeyError in _get_ephemeral parsing generateEphemeralCert: %s. Response dict: %s",
283
+ e,
284
+ ret_dict,
285
+ )
286
+ raise
275
287
 
276
288
  # decode cert to read expiration
277
289
  x509 = load_pem_x509_certificate(
@@ -285,7 +297,7 @@ class CloudSQLClient:
285
297
  # google.auth library strips timezone info for backwards compatibality
286
298
  # reasons with Python 2. Add it back to allow timezone aware datetimes.
287
299
  # Ref: https://github.com/googleapis/google-auth-library-python/blob/49a5ff7411a2ae4d32a7d11700f9f961c55406a9/google/auth/_helpers.py#L93-L99
288
- token_expiration = token_expiration.replace(tzinfo=datetime.timezone.utc)
300
+ token_expiration = token_expiration.replace(tzinfo=datetime.UTC)
289
301
 
290
302
  expiration = min(expiration, token_expiration)
291
303
  return ephemeral_cert, expiration
@@ -21,6 +21,7 @@ import ssl
21
21
  from typing import Any, TYPE_CHECKING
22
22
 
23
23
  from google.cloud.sql.connector.connection_name import ConnectionName
24
+ from google.cloud.sql.connector.exceptions import CloudSQLConnectionError
24
25
  from google.cloud.sql.connector.exceptions import CloudSQLIPTypeError
25
26
  from google.cloud.sql.connector.exceptions import TLSVersionError
26
27
  from google.cloud.sql.connector.utils import AsyncTemporaryDirectory
@@ -45,6 +46,10 @@ class ConnectionInfoCache(abc.ABC):
45
46
  async def force_refresh(self) -> None:
46
47
  pass
47
48
 
49
+ @abc.abstractmethod
50
+ def record_principal(self, user: str, database: str) -> None:
51
+ pass
52
+
48
53
  @abc.abstractmethod
49
54
  async def close(self) -> None:
50
55
  pass
@@ -62,7 +67,7 @@ class ConnectionInfo:
62
67
 
63
68
  conn_name: ConnectionName
64
69
  client_cert: str
65
- server_ca_cert: str
70
+ server_ca_cert: str | None
66
71
  private_key: bytes
67
72
  ip_addrs: dict[str, Any]
68
73
  database_version: str
@@ -78,6 +83,12 @@ class ConnectionInfo:
78
83
  # if SSL context is cached, use it
79
84
  if self.context is not None:
80
85
  return self.context
86
+
87
+ if self.server_ca_cert is None:
88
+ raise CloudSQLConnectionError(
89
+ "Cannot create SSL context: server CA certificate is missing."
90
+ )
91
+
81
92
  context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
82
93
 
83
94
  # update ssl.PROTOCOL_TLS_CLIENT default