cloud-sql-python-connector 1.17.0.dev0__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.
@@ -0,0 +1,838 @@
1
+ Metadata-Version: 2.2
2
+ Name: cloud-sql-python-connector
3
+ Version: 1.17.0.dev0
4
+ Summary: Google Cloud SQL Python Connector library
5
+ Author-email: Google LLC <googleapis-packages@google.com>
6
+ License: 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
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Operating System :: OS Independent
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: aiofiles
26
+ Requires-Dist: aiohttp
27
+ Requires-Dist: cryptography>=42.0.0
28
+ Requires-Dist: dnspython>=2.0.0
29
+ Requires-Dist: Requests
30
+ Requires-Dist: google-auth>=2.28.0
31
+ Provides-Extra: pymysql
32
+ Requires-Dist: PyMySQL>=1.1.0; extra == "pymysql"
33
+ Provides-Extra: pg8000
34
+ Requires-Dist: pg8000>=1.31.1; extra == "pg8000"
35
+ Provides-Extra: pytds
36
+ Requires-Dist: python-tds>=1.15.0; extra == "pytds"
37
+ Provides-Extra: asyncpg
38
+ Requires-Dist: asyncpg>=0.30.0; extra == "asyncpg"
39
+
40
+ <p align="center">
41
+ <a href="https://cloud.google.com/blog/topics/developers-practitioners/how-connect-cloud-sql-using-python-easy-way">
42
+ <img src="https://raw.githubusercontent.com/GoogleCloudPlatform/cloud-sql-python-connector/main/docs/images/cloud-sql-python-connector.png" alt="cloud-sql-python-connector image">
43
+ </a>
44
+ </p>
45
+
46
+ <h1 align="center">Cloud SQL Python Connector</h1>
47
+
48
+ [![Open In Colab][colab-badge]][colab-notebook]
49
+ [![CI][ci-badge]][ci-build]
50
+ [![pypi][pypi-badge]][pypi-docs]
51
+ [![PyPI download month][pypi-downloads]][pypi-docs]
52
+ [![python][python-versions]][pypi-docs]
53
+
54
+ [colab-badge]: https://colab.research.google.com/assets/colab-badge.svg
55
+ [colab-notebook]: https://colab.research.google.com/github/GoogleCloudPlatform/cloud-sql-python-connector/blob/main/samples/notebooks/postgres_python_connector.ipynb
56
+ [ci-badge]: https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/actions/workflows/tests.yml/badge.svg?event=push
57
+ [ci-build]: https://github.com/GoogleCloudPlatform/cloud-sql-python-connector/actions/workflows/tests.yml?query=event%3Apush+branch%3Amain
58
+ [pypi-badge]: https://img.shields.io/pypi/v/cloud-sql-python-connector
59
+ [pypi-docs]: https://pypi.org/project/cloud-sql-python-connector
60
+ [pypi-downloads]: https://img.shields.io/pypi/dm/cloud-sql-python-connector.svg
61
+ [python-versions]: https://img.shields.io/pypi/pyversions/cloud-sql-python-connector
62
+
63
+ The _Cloud SQL Python Connector_ is a Cloud SQL connector designed for use with the
64
+ Python language. Using a Cloud SQL connector provides a native alternative to the
65
+ [Cloud SQL Auth Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy) while
66
+ providing the following benefits:
67
+
68
+ * **IAM Authorization:** uses IAM permissions to control who/what can connect to
69
+ your Cloud SQL instances
70
+ * **Improved Security:** uses robust, updated TLS 1.3 encryption and
71
+ identity verification between the client connector and the server-side proxy,
72
+ independent of the database protocol.
73
+ * **Convenience:** removes the requirement to use and distribute SSL
74
+ certificates, as well as manage firewalls or source/destination IP addresses.
75
+ * (optionally) **IAM DB Authentication:** provides support for
76
+ [Cloud SQL’s automatic IAM DB AuthN][iam-db-authn] feature.
77
+
78
+ [iam-db-authn]: https://cloud.google.com/sql/docs/postgres/authentication
79
+
80
+ The Cloud SQL Python Connector is a package to be used alongside a database driver.
81
+ Currently supported drivers are:
82
+ - [`pymysql`](https://github.com/PyMySQL/PyMySQL) (MySQL)
83
+ - [`pg8000`](https://github.com/tlocke/pg8000) (PostgreSQL)
84
+ - [`asyncpg`](https://github.com/MagicStack/asyncpg) (PostgreSQL)
85
+ - [`pytds`](https://github.com/denisenkom/pytds) (SQL Server)
86
+
87
+
88
+ ## Installation
89
+
90
+ You can install this library with `pip install`, specifying the driver
91
+ based on your database dialect.
92
+
93
+ ### MySQL
94
+ ```
95
+ pip install "cloud-sql-python-connector[pymysql]"
96
+ ```
97
+ ### Postgres
98
+ There are two different database drivers that are supported for the Postgres dialect:
99
+
100
+ #### pg8000
101
+ ```
102
+ pip install "cloud-sql-python-connector[pg8000]"
103
+ ```
104
+ #### asyncpg
105
+ ```
106
+ pip install "cloud-sql-python-connector[asyncpg]"
107
+ ```
108
+ ### SQL Server
109
+ ```
110
+ pip install "cloud-sql-python-connector[pytds]"
111
+ ```
112
+
113
+ ### APIs and Services
114
+
115
+ This package requires the following to successfully make Cloud SQL Connections:
116
+
117
+ - IAM principal (user, service account, etc.) with the
118
+ [Cloud SQL Client][client-role] role. This IAM principal will be used for
119
+ [credentials](#credentials).
120
+ - The [Cloud SQL Admin API][admin-api] to be enabled within your Google Cloud
121
+ Project. By default, the API will be called in the project associated with
122
+ the IAM principal.
123
+
124
+ [admin-api]: https://console.cloud.google.com/apis/api/sqladmin.googleapis.com
125
+ [client-role]: https://cloud.google.com/sql/docs/mysql/roles-and-permissions
126
+
127
+ ### Credentials
128
+
129
+ This library uses the [Application Default Credentials (ADC)][adc] strategy for
130
+ resolving credentials. Please see [these instructions for how to set your ADC][set-adc]
131
+ (Google Cloud Application vs Local Development, IAM user vs service account credentials),
132
+ or consult the [google.auth][google-auth] package.
133
+
134
+ To explicitly set a specific source for the credentials, see
135
+ [Configuring the Connector](#configuring-the-connector) below.
136
+
137
+ [adc]: https://cloud.google.com/docs/authentication#adc
138
+ [set-adc]: https://cloud.google.com/docs/authentication/provide-credentials-adc
139
+ [google-auth]: https://google-auth.readthedocs.io/en/master/reference/google.auth.html
140
+
141
+ ## Usage
142
+
143
+ This package provides several functions for authorizing and encrypting
144
+ connections. These functions are used with your database driver to connect to
145
+ your Cloud SQL instance.
146
+
147
+ The instance connection name for your Cloud SQL instance is always in the
148
+ format "project:region:instance".
149
+
150
+ ### How to use this Connector
151
+
152
+ To connect to Cloud SQL using the connector, inititalize a `Connector`
153
+ object and call its `connect` method with the proper input parameters.
154
+
155
+ The `Connector` itself creates connection objects by calling its `connect` method but does not manage database connection pooling. For this reason, it is recommended to use the connector alongside a library that can create connection pools, such as [SQLAlchemy](https://www.sqlalchemy.org/). This will allow for connections to remain open and be reused, reducing connection overhead and the number of connections needed.
156
+
157
+ In the Connector's `connect` method below, input your connection string as the first positional argument and the name of the database driver for the second positional argument. Insert the rest of your connection keyword arguments like user, password and database. You can also set the optional `timeout` or `ip_type` keyword arguments.
158
+
159
+ To use this connector with SQLAlchemy, use the `creator` argument for `sqlalchemy.create_engine`:
160
+
161
+ ```python
162
+ from google.cloud.sql.connector import Connector
163
+ import sqlalchemy
164
+
165
+ # initialize Connector object
166
+ connector = Connector()
167
+
168
+ # function to return the database connection
169
+ def getconn() -> pymysql.connections.Connection:
170
+ conn: pymysql.connections.Connection = connector.connect(
171
+ "project:region:instance",
172
+ "pymysql",
173
+ user="my-user",
174
+ password="my-password",
175
+ db="my-db-name"
176
+ )
177
+ return conn
178
+
179
+ # create connection pool
180
+ pool = sqlalchemy.create_engine(
181
+ "mysql+pymysql://",
182
+ creator=getconn,
183
+ )
184
+ ```
185
+
186
+ The returned connection pool engine can then be used to query and modify the database.
187
+
188
+ ```python
189
+ # insert statement
190
+ insert_stmt = sqlalchemy.text(
191
+ "INSERT INTO my_table (id, title) VALUES (:id, :title)",
192
+ )
193
+
194
+ with pool.connect() as db_conn:
195
+ # insert into database
196
+ db_conn.execute(insert_stmt, parameters={"id": "book1", "title": "Book One"})
197
+
198
+ # query database
199
+ result = db_conn.execute(sqlalchemy.text("SELECT * from my_table")).fetchall()
200
+
201
+ # commit transaction (SQLAlchemy v2.X.X is commit as you go)
202
+ db_conn.commit()
203
+
204
+ # Do something with the results
205
+ for row in result:
206
+ print(row)
207
+ ```
208
+
209
+ To close the `Connector` object's background resources, call its `close()` method as follows:
210
+
211
+ ```python
212
+ connector.close()
213
+ ```
214
+
215
+ > [!NOTE]
216
+ >
217
+ > For more examples of using SQLAlchemy to manage connection pooling with the connector,
218
+ > please see [Cloud SQL SQLAlchemy Samples](https://cloud.google.com/sql/docs/postgres/connect-connectors#python_1).
219
+
220
+ ### Configuring the Connector
221
+
222
+ If you need to customize something about the connector, or want to specify
223
+ defaults for each connection to make, you can initialize a
224
+ `Connector` object as follows:
225
+
226
+ ```python
227
+ from google.cloud.sql.connector import Connector
228
+
229
+ # Note: all parameters below are optional
230
+ connector = Connector(
231
+ ip_type="public", # can also be "private" or "psc"
232
+ enable_iam_auth=False,
233
+ timeout=30,
234
+ credentials=custom_creds, # google.auth.credentials.Credentials
235
+ refresh_strategy="lazy", # can be "lazy" or "background"
236
+ )
237
+ ```
238
+
239
+ ### Using Connector as a Context Manager
240
+
241
+ The `Connector` object can also be used as a context manager in order to
242
+ automatically close and cleanup resources, removing the need for explicit
243
+ calls to `connector.close()`.
244
+
245
+ Connector as a context manager:
246
+
247
+ ```python
248
+ from google.cloud.sql.connector import Connector
249
+ import pymysql
250
+ import sqlalchemy
251
+
252
+ # helper function to return SQLAlchemy connection pool
253
+ def init_connection_pool(connector: Connector) -> sqlalchemy.engine.Engine:
254
+ # function used to generate database connection
255
+ def getconn() -> pymysql.connections.Connection:
256
+ conn = connector.connect(
257
+ "project:region:instance",
258
+ "pymysql",
259
+ user="my-user",
260
+ password="my-password",
261
+ db="my-db-name"
262
+ )
263
+ return conn
264
+
265
+ # create connection pool
266
+ pool = sqlalchemy.create_engine(
267
+ "mysql+pymysql://",
268
+ creator=getconn,
269
+ )
270
+ return pool
271
+
272
+ # initialize Cloud SQL Python Connector as context manager
273
+ with Connector() as connector:
274
+ # initialize connection pool
275
+ pool = init_connection_pool(connector)
276
+ # insert statement
277
+ insert_stmt = sqlalchemy.text(
278
+ "INSERT INTO my_table (id, title) VALUES (:id, :title)",
279
+ )
280
+
281
+ # interact with Cloud SQL database using connection pool
282
+ with pool.connect() as db_conn:
283
+ # insert into database
284
+ db_conn.execute(insert_stmt, parameters={"id": "book1", "title": "Book One"})
285
+
286
+ # commit transaction (SQLAlchemy v2.X.X is commit as you go)
287
+ db_conn.commit()
288
+
289
+ # query database
290
+ result = db_conn.execute(sqlalchemy.text("SELECT * from my_table")).fetchall()
291
+
292
+ # Do something with the results
293
+ for row in result:
294
+ print(row)
295
+ ```
296
+
297
+ ### Configuring a Lazy Refresh (Cloud Run, Cloud Functions etc.)
298
+
299
+ The Connector's `refresh_strategy` argument can be set to `"lazy"` to configure
300
+ the Python Connector to retrieve connection info lazily and as-needed.
301
+ Otherwise, a background refresh cycle runs to retrive the connection info
302
+ periodically. This setting is useful in environments where the CPU may be
303
+ throttled outside of a request context, e.g., Cloud Run, Cloud Functions, etc.
304
+
305
+ To set the refresh strategy, set the `refresh_strategy` keyword argument when
306
+ initializing a `Connector`:
307
+
308
+ ```python
309
+ connector = Connector(refresh_strategy="lazy")
310
+ ```
311
+
312
+ ### Specifying IP Address Type
313
+
314
+ The Cloud SQL Python Connector can be used to connect to Cloud SQL instances
315
+ using both public and private IP addresses, as well as
316
+ [Private Service Connect][psc] (PSC). To specify which IP address type to connect
317
+ with, set the `ip_type` keyword argument when initializing a `Connector()` or when
318
+ calling `connector.connect()`.
319
+
320
+ Possible values for `ip_type` are `"public"` (default value),
321
+ `"private"`, and `"psc"`.
322
+
323
+ Example:
324
+
325
+ ```python
326
+ conn = connector.connect(
327
+ "project:region:instance",
328
+ "pymysql",
329
+ ip_type="private" # use private IP
330
+ ... insert other kwargs ...
331
+ )
332
+ ```
333
+
334
+ > [!IMPORTANT]
335
+ >
336
+ > If specifying Private IP or Private Service Connect (PSC), your application must be
337
+ > attached to the proper VPC network to connect to your Cloud SQL instance. For most
338
+ > applications this will require the use of a [VPC Connector][vpc-connector].
339
+
340
+ [psc]: https://cloud.google.com/vpc/docs/private-service-connect
341
+ [vpc-connector]: https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#create-connector
342
+
343
+ ### Automatic IAM Database Authentication
344
+
345
+ Connections using [Automatic IAM database authentication](https://cloud.google.com/sql/docs/postgres/authentication#automatic) are supported when using Postgres or MySQL drivers.
346
+ First, make sure to [configure your Cloud SQL Instance to allow IAM authentication](https://cloud.google.com/sql/docs/postgres/create-edit-iam-instances#configure-iam-db-instance)
347
+ and [add an IAM database user](https://cloud.google.com/sql/docs/postgres/create-manage-iam-users#creating-a-database-user).
348
+
349
+ Now, you can connect using user or service account credentials instead of a password.
350
+ In the call to connect, set the `enable_iam_auth` keyword argument to true and the `user` argument to the appropriately formatted IAM principal.
351
+ > Postgres: For an IAM user account, this is the user's email address. For a service account, it is the service account's email without the `.gserviceaccount.com` domain suffix.
352
+
353
+ > MySQL: For an IAM user account, this is the user's email address, without the @ or domain name. For example, for `test-user@gmail.com`, set the `user` argument to `test-user`. For a service account, this is the service account's email address without the `@project-id.iam.gserviceaccount.com` suffix.
354
+
355
+ Example:
356
+
357
+ ```python
358
+ conn = connector.connect(
359
+ "project:region:instance",
360
+ "pg8000",
361
+ user="postgres-iam-user@gmail.com",
362
+ db="my-db-name",
363
+ enable_iam_auth=True,
364
+ )
365
+ ```
366
+
367
+ ### SQL Server (MSSQL)
368
+
369
+ > [!IMPORTANT]
370
+ >
371
+ > If your SQL Server instance is set to [enforce SSL connections](https://cloud.google.com/sql/docs/sqlserver/configure-ssl-instance#enforcing-ssl),
372
+ > you need to download the CA certificate for your instance and include `cafile={path to downloaded certificate}`
373
+ > and `validate_host=False`. This is a workaround for a [known issue](https://issuetracker.google.com/184867147).
374
+
375
+ #### Active Directory Authentication
376
+
377
+ Active Directory authentication for SQL Server instances is currently only supported on Windows.
378
+ First, make sure to follow [these steps](https://cloud.google.com/blog/topics/developers-practitioners/creating-sql-server-instance-integrated-active-directory-using-google-cloud-sql)
379
+ to set up a Managed AD domain and join your Cloud SQL instance to the domain.
380
+ [See here for more info on Cloud SQL Active Directory integration](https://cloud.google.com/sql/docs/sqlserver/ad).
381
+
382
+ Once you have followed the steps linked above, you can run the following code to return a connection object:
383
+
384
+ ```python
385
+ conn = connector.connect(
386
+ "project:region:instance",
387
+ "pytds",
388
+ db="my-db-name",
389
+ active_directory_auth=True,
390
+ server_name="public.[instance].[location].[project].cloudsql.[domain]",
391
+ )
392
+ ```
393
+
394
+ Or, if using Private IP:
395
+
396
+ ```python
397
+ conn = connector.connect(
398
+ "project:region:instance",
399
+ "pytds",
400
+ db="my-db-name",
401
+ active_directory_auth=True,
402
+ server_name="private.[instance].[location].[project].cloudsql.[domain]",
403
+ ip_type="private"
404
+ )
405
+ ```
406
+
407
+ ### Using DNS domain names to identify instances
408
+
409
+ The connector can be configured to use DNS to look up an instance. This would
410
+ allow you to configure your application to connect to a database instance, and
411
+ centrally configure which instance in your DNS zone.
412
+
413
+ #### Configure your DNS Records
414
+
415
+ Add a DNS TXT record for the Cloud SQL instance to a **private** DNS server
416
+ or a private Google Cloud DNS Zone used by your application.
417
+
418
+ > [!NOTE]
419
+ >
420
+ > You are strongly discouraged from adding DNS records for your
421
+ > Cloud SQL instances to a public DNS server. This would allow anyone on the
422
+ > internet to discover the Cloud SQL instance name.
423
+
424
+ For example: suppose you wanted to use the domain name
425
+ `prod-db.mycompany.example.com` to connect to your database instance
426
+ `my-project:region:my-instance`. You would create the following DNS record:
427
+
428
+ * Record type: `TXT`
429
+ * Name: `prod-db.mycompany.example.com` – This is the domain name used by the application
430
+ * Value: `my-project:my-region:my-instance` – This is the Cloud SQL instance connection name
431
+
432
+ #### Configure the connector
433
+
434
+ Configure the connector to resolve DNS names by initializing it with
435
+ `resolver=DnsResolver` and replacing the instance connection name with the DNS
436
+ name in `connector.connect`:
437
+
438
+ ```python
439
+ from google.cloud.sql.connector import Connector, DnsResolver
440
+ import pymysql
441
+ import sqlalchemy
442
+
443
+ # helper function to return SQLAlchemy connection pool
444
+ def init_connection_pool(connector: Connector) -> sqlalchemy.engine.Engine:
445
+ # function used to generate database connection
446
+ def getconn() -> pymysql.connections.Connection:
447
+ conn = connector.connect(
448
+ "prod-db.mycompany.example.com", # using DNS name
449
+ "pymysql",
450
+ user="my-user",
451
+ password="my-password",
452
+ db="my-db-name"
453
+ )
454
+ return conn
455
+
456
+ # create connection pool
457
+ pool = sqlalchemy.create_engine(
458
+ "mysql+pymysql://",
459
+ creator=getconn,
460
+ )
461
+ return pool
462
+
463
+ # initialize Cloud SQL Python Connector with `resolver=DnsResolver`
464
+ with Connector(resolver=DnsResolver) as connector:
465
+ # initialize connection pool
466
+ pool = init_connection_pool(connector)
467
+ # ... use SQLAlchemy engine normally
468
+ ```
469
+
470
+ ### Using the Python Connector with Python Web Frameworks
471
+
472
+ The Python Connector can be used alongside popular Python web frameworks such
473
+ as Flask, FastAPI, etc, to integrate Cloud SQL databases within your
474
+ web applications.
475
+
476
+ > [!NOTE]
477
+ >
478
+ > For serverless environments such as Cloud Functions, Cloud Run, etc, it may be
479
+ > beneficial to initialize the `Connector` with the lazy refresh strategy.
480
+ > i.e. `Connector(refresh_strategy="lazy")`
481
+ >
482
+ > See [Configuring a Lazy Refresh](#configuring-a-lazy-refresh-cloud-run-cloud-functions-etc)
483
+
484
+ #### Flask-SQLAlchemy
485
+
486
+ [Flask-SQLAlchemy](https://flask-sqlalchemy.palletsprojects.com/en/2.x/)
487
+ is an extension for [Flask](https://flask.palletsprojects.com/en/2.2.x/)
488
+ that adds support for [SQLAlchemy](https://www.sqlalchemy.org/) to your
489
+ application. It aims to simplify using SQLAlchemy with Flask by providing
490
+ useful defaults and extra helpers that make it easier to accomplish
491
+ common tasks.
492
+
493
+ You can configure Flask-SQLAlchemy to connect to a Cloud SQL database from
494
+ your web application through the following:
495
+
496
+ ```python
497
+ from flask import Flask
498
+ from flask_sqlalchemy import SQLAlchemy
499
+ from google.cloud.sql.connector import Connector
500
+
501
+
502
+ # initialize Python Connector object
503
+ connector = Connector()
504
+
505
+ # Python Connector database connection function
506
+ def getconn():
507
+ conn = connector.connect(
508
+ "project:region:instance-name", # Cloud SQL Instance Connection Name
509
+ "pg8000",
510
+ user="my-user",
511
+ password="my-password",
512
+ db="my-database",
513
+ ip_type="public" # "private" for private IP
514
+ )
515
+ return conn
516
+
517
+
518
+ app = Flask(__name__)
519
+
520
+ # configure Flask-SQLAlchemy to use Python Connector
521
+ app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql+pg8000://"
522
+ app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
523
+ "creator": getconn
524
+ }
525
+
526
+ # initialize the app with the extension
527
+ db = SQLAlchemy()
528
+ db.init_app(app)
529
+ ```
530
+
531
+ For more details on how to use Flask-SQLAlchemy, check out the
532
+ [Flask-SQLAlchemy Quickstarts](https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/quickstart/)
533
+
534
+ #### FastAPI
535
+
536
+ [FastAPI](https://fastapi.tiangolo.com/) is a modern, fast (high-performance),
537
+ web framework for building APIs with Python based on standard Python type hints.
538
+
539
+ You can configure FastAPI to connect to a Cloud SQL database from
540
+ your web application using [SQLAlchemy ORM](https://docs.sqlalchemy.org/en/14/orm/)
541
+ through the following:
542
+
543
+ ```python
544
+ from sqlalchemy import create_engine
545
+ from sqlalchemy.engine import Engine
546
+ from sqlalchemy.ext.declarative import declarative_base
547
+ from sqlalchemy.orm import sessionmaker
548
+ from google.cloud.sql.connector import Connector
549
+
550
+ # helper function to return SQLAlchemy connection pool
551
+ def init_connection_pool(connector: Connector) -> Engine:
552
+ # Python Connector database connection function
553
+ def getconn():
554
+ conn = connector.connect(
555
+ "project:region:instance-name", # Cloud SQL Instance Connection Name
556
+ "pg8000",
557
+ user="my-user",
558
+ password="my-password",
559
+ db="my-database",
560
+ ip_type="public" # "private" for private IP
561
+ )
562
+ return conn
563
+
564
+ SQLALCHEMY_DATABASE_URL = "postgresql+pg8000://"
565
+
566
+ engine = create_engine(
567
+ SQLALCHEMY_DATABASE_URL , creator=getconn
568
+ )
569
+ return engine
570
+
571
+ # initialize Cloud SQL Python Connector
572
+ connector = Connector()
573
+
574
+ # create connection pool engine
575
+ engine = init_connection_pool(connector)
576
+
577
+ # create SQLAlchemy ORM session
578
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
579
+
580
+ Base = declarative_base()
581
+ ```
582
+
583
+ To learn more about integrating a database into your FastAPI application,
584
+ follow along the [FastAPI SQL Database guide](https://fastapi.tiangolo.com/tutorial/sql-databases/#create-the-database-models).
585
+
586
+ ### Async Driver Usage
587
+
588
+ The Cloud SQL Connector is compatible with
589
+ [asyncio](https://docs.python.org/3/library/asyncio.html) to improve the speed
590
+ and efficiency of database connections through concurrency. You can use all
591
+ non-asyncio drivers through the `Connector.connect_async` function, in addition
592
+ to the following asyncio database drivers:
593
+ - [asyncpg](https://magicstack.github.io/asyncpg) (Postgres)
594
+
595
+ The Cloud SQL Connector has a helper `create_async_connector` function that is
596
+ recommended for asyncio database connections. It returns a `Connector`
597
+ object that uses the current thread's running event loop. This is different
598
+ than `Connector()` which by default initializes a new event loop in a
599
+ background thread.
600
+
601
+ The `create_async_connector` allows all the same input arguments as the
602
+ [Connector](#configuring-the-connector) object.
603
+
604
+ Once a `Connector` object is returned by `create_async_connector` you can call
605
+ its `connect_async` method, just as you would the `connect` method:
606
+
607
+ #### Asyncpg Connection Pool
608
+
609
+ ```python
610
+ import asyncpg
611
+ from google.cloud.sql.connector import Connector, create_async_connector
612
+
613
+ async def main():
614
+ # initialize Connector object for connections to Cloud SQL
615
+ connector = create_async_connector()
616
+
617
+ # creation function to generate asyncpg connections as the 'connect' arg
618
+ async def getconn(instance_connection_name, **kwargs) -> asyncpg.Connection:
619
+ return await connector.connect_async(
620
+ instance_connection_name,
621
+ "asyncpg",
622
+ user="my-user",
623
+ password="my-password",
624
+ db="my-db",
625
+ **kwargs, # ... additional asyncpg args
626
+ )
627
+
628
+ # initialize connection pool
629
+ pool = await asyncpg.create_pool(
630
+ "my-project:my-region:my-instance", connect=getconn
631
+ )
632
+
633
+ # acquire connection and query Cloud SQL database
634
+ async with pool.acquire() as conn:
635
+ res = await conn.fetch("SELECT NOW()")
636
+
637
+ # close Connector
638
+ await connector.close_async()
639
+ ```
640
+
641
+ #### SQLAlchemy Async Engine
642
+
643
+ ```python
644
+ import asyncpg
645
+
646
+ import sqlalchemy
647
+ from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
648
+
649
+ from google.cloud.sql.connector import Connector, create_async_connector
650
+
651
+ async def init_connection_pool(connector: Connector) -> AsyncEngine:
652
+ # creation function to generate asyncpg connections as 'async_creator' arg
653
+ async def getconn() -> asyncpg.Connection:
654
+ conn: asyncpg.Connection = await connector.connect_async(
655
+ "project:region:instance", # Cloud SQL instance connection name
656
+ "asyncpg",
657
+ user="my-user",
658
+ password="my-password",
659
+ db="my-db-name"
660
+ # ... additional database driver args
661
+ )
662
+ return conn
663
+
664
+ # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
665
+ # 'async_creator' argument to 'create_async_engine'
666
+ pool = create_async_engine(
667
+ "postgresql+asyncpg://",
668
+ async_creator=getconn,
669
+ )
670
+ return pool
671
+
672
+ async def main():
673
+ # initialize Connector object for connections to Cloud SQL
674
+ connector = await create_async_connector()
675
+
676
+ # initialize connection pool
677
+ pool = await init_connection_pool(connector)
678
+
679
+ # example query
680
+ async with pool.connect() as conn:
681
+ await conn.execute(sqlalchemy.text("SELECT NOW()"))
682
+
683
+ # close Connector
684
+ await connector.close_async()
685
+
686
+ # dispose of connection pool
687
+ await pool.dispose()
688
+ ```
689
+
690
+ For more details on additional database arguments with an `asyncpg.Connection`
691
+ , please visit the
692
+ [official documentation](https://magicstack.github.io/asyncpg/current/api/index.html).
693
+
694
+ ### Async Context Manager
695
+
696
+ An alternative to using the `create_async_connector` function is initializing
697
+ a `Connector` as an async context manager, removing the need for explicit
698
+ calls to `connector.close_async()` to cleanup resources.
699
+
700
+ > [!NOTE]
701
+ >
702
+ > This alternative requires that the running event loop be
703
+ > passed in as the `loop` argument to `Connector()`.
704
+
705
+ #### Asyncpg Connection Pool
706
+
707
+ ```python
708
+ import asyncpg
709
+ from google.cloud.sql.connector import Connector, create_async_connector
710
+
711
+ async def main():
712
+ # initialize Connector object for connections to Cloud SQL
713
+ loop = asyncio.get_running_loop()
714
+ async with Connector(loop=loop) as connector:
715
+
716
+ # creation function to generate asyncpg connections as the 'connect' arg
717
+ async def getconn(instance_connection_name, **kwargs) -> asyncpg.Connection:
718
+ return await connector.connect_async(
719
+ instance_connection_name,
720
+ "asyncpg",
721
+ user="my-user",
722
+ password="my-password",
723
+ db="my-db",
724
+ **kwargs, # ... additional asyncpg args
725
+ )
726
+
727
+ # create connection pool
728
+ pool = await asyncpg.create_pool(
729
+ "my-project:my-region:my-instance", connect=getconn
730
+ )
731
+
732
+ # acquire connection and query Cloud SQL database
733
+ async with pool.acquire() as conn:
734
+ res = await conn.fetch("SELECT NOW()")
735
+ ```
736
+
737
+ #### SQLAlchemy Async Engine
738
+
739
+ ```python
740
+ import asyncio
741
+ import asyncpg
742
+
743
+ import sqlalchemy
744
+ from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
745
+
746
+ from google.cloud.sql.connector import Connector
747
+
748
+ async def init_connection_pool(connector: Connector) -> AsyncEngine:
749
+ # creation function to generate asyncpg connections as 'async_creator' arg
750
+ async def getconn() -> asyncpg.Connection:
751
+ conn: asyncpg.Connection = await connector.connect_async(
752
+ "project:region:instance", # Cloud SQL instance connection name
753
+ "asyncpg",
754
+ user="my-user",
755
+ password="my-password",
756
+ db="my-db-name"
757
+ # ... additional database driver args
758
+ )
759
+ return conn
760
+
761
+ # The Cloud SQL Python Connector can be used along with SQLAlchemy using the
762
+ # 'async_creator' argument to 'create_async_engine'
763
+ pool = create_async_engine(
764
+ "postgresql+asyncpg://",
765
+ async_creator=getconn,
766
+ )
767
+ return pool
768
+
769
+ async def main():
770
+ # initialize Connector object for connections to Cloud SQL
771
+ loop = asyncio.get_running_loop()
772
+ async with Connector(loop=loop) as connector:
773
+ # initialize connection pool
774
+ pool = await init_connection_pool(connector)
775
+
776
+ # example query
777
+ async with pool.connect() as conn:
778
+ await conn.execute(sqlalchemy.text("SELECT NOW()"))
779
+
780
+ # dispose of connection pool
781
+ await pool.dispose()
782
+ ```
783
+
784
+ ### Debug Logging
785
+
786
+ The Cloud SQL Python Connector uses the standard [Python logging module][python-logging]
787
+ for debug logging support.
788
+
789
+ Add the below code to your application to enable debug logging with the Cloud SQL
790
+ Python Connector:
791
+
792
+ ```python
793
+ import logging
794
+
795
+ logging.basicConfig(format="%(asctime)s [%(levelname)s]: %(message)s")
796
+ logger = logging.getLogger(name="google.cloud.sql.connector")
797
+ logger.setLevel(logging.DEBUG)
798
+ ```
799
+
800
+ For more details on configuring logging, please refer to the
801
+ [Python logging docs][configure-logging].
802
+
803
+ [python-logging]: https://docs.python.org/3/library/logging.html
804
+ [configure-logging]: https://docs.python.org/3/howto/logging.html#configuring-logging
805
+
806
+ ## Support policy
807
+
808
+ ### Major version lifecycle
809
+
810
+ This project uses [semantic versioning](https://semver.org/), and uses the
811
+ following lifecycle regarding support for a major version:
812
+
813
+ **Active** - Active versions get all new features and security fixes (that
814
+ wouldn’t otherwise introduce a breaking change). New major versions are
815
+ guaranteed to be "active" for a minimum of 1 year.
816
+ **Deprecated** - Deprecated versions continue to receive security and critical
817
+ bug fixes, but do not receive new features. Deprecated versions will be publicly
818
+ supported for 1 year.
819
+ **Unsupported** - Any major version that has been deprecated for >=1 year is
820
+ considered publicly unsupported.
821
+
822
+ ### Supported Python Versions
823
+
824
+ We follow the [Python Version Support Policy][pyver] used by Google Cloud
825
+ Libraries for Python. Changes in supported Python versions will be
826
+ considered a minor change, and will be listed in the release notes.
827
+
828
+ [pyver]: https://cloud.google.com/python/docs/supported-python-versions
829
+
830
+ ### Release cadence
831
+ This project aims for a minimum monthly release cadence. If no new
832
+ features or fixes have been added, a new PATCH version with the latest
833
+ dependencies is released.
834
+
835
+ ### Contributing
836
+
837
+ We welcome outside contributions. Please see our
838
+ [Contributing Guide](CONTRIBUTING.md) for details on how best to contribute.