3838from google .cloud .sql .connector .exceptions import ConnectorLoopError
3939from google .cloud .sql .connector .instance import RefreshAheadCache
4040from google .cloud .sql .connector .lazy import LazyRefreshCache
41+ import google .cloud .sql .connector .local_unix_socket as local_unix_socket
4142from google .cloud .sql .connector .monitored_cache import MonitoredCache
4243import google .cloud .sql .connector .pg8000 as pg8000
43- import google .cloud .sql .connector .proxy as proxy
44- import google .cloud .sql .connector .psycopg as psycopg
44+ from google .cloud .sql .connector .proxy import Proxy
4545import google .cloud .sql .connector .pymysql as pymysql
4646import google .cloud .sql .connector .pytds as pytds
4747from google .cloud .sql .connector .resolver import DefaultResolver
5252logger = logging .getLogger (name = __name__ )
5353
5454ASYNC_DRIVERS = ["asyncpg" ]
55- LOCAL_PROXY_DRIVERS = ["psycopg" ]
5655SERVER_PROXY_PORT = 3307
5756_DEFAULT_SCHEME = "https://"
5857_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
@@ -160,7 +159,7 @@ def __init__(
160159 self ._cache : dict [tuple [str , bool ], MonitoredCache ] = {}
161160 self ._client : Optional [CloudSQLClient ] = None
162161 self ._closed : bool = False
163- self ._proxy : Optional [asyncio . Task ] = None
162+ self ._proxies : Optional [Proxy ] = None
164163
165164 # initialize credentials
166165 scopes = ["https://www.googleapis.com/auth/sqlservice.admin" ]
@@ -221,6 +220,29 @@ def __init__(
221220 def universe_domain (self ) -> str :
222221 return self ._universe_domain or _DEFAULT_UNIVERSE_DOMAIN
223222
223+ def start_unix_socket_proxy_async (
224+ self ,
225+ instance_connection_name : str ,
226+ local_socket_path : str ,
227+ ** kwargs : Any
228+ ) -> None :
229+ """Creates a new Proxy instance and stores it to properly disposal
230+
231+ Args:
232+ instance_connection_string (str): The instance connection name of the
233+ Cloud SQL instance to connect to. Takes the form of
234+ "project-id:region:instance-name"
235+
236+ Example: "my-project:us-central1:my-instance"
237+
238+ local_socket_path (str): A string representing the location of the local socket.
239+
240+ **kwargs: Any driver-specific arguments to pass to the underlying
241+ driver .connect call.
242+ """
243+ # TODO: validates the local socket path is not the same as other invocation
244+ self ._proxies .append (new Proxy (self , instance_connection_name , local_socket_path , self .loop , ** kwargs ))
245+
224246 def connect (
225247 self , instance_connection_string : str , driver : str , ** kwargs : Any
226248 ) -> Any :
@@ -238,7 +260,7 @@ def connect(
238260 Example: "my-project:us-central1:my-instance"
239261
240262 driver (str): A string representing the database driver to connect
241- with. Supported drivers are pymysql, pg8000, psycopg , and pytds.
263+ with. Supported drivers are pymysql, pg8000, local_unix_socket , and pytds.
242264
243265 **kwargs: Any driver-specific arguments to pass to the underlying
244266 driver .connect call.
@@ -280,7 +302,7 @@ async def connect_async(
280302 Example: "my-project:us-central1:my-instance"
281303
282304 driver (str): A string representing the database driver to connect
283- with. Supported drivers are pymysql, asyncpg, pg8000, psycopg , and
305+ with. Supported drivers are pymysql, asyncpg, pg8000, local_unix_socket , and
284306 pytds.
285307
286308 **kwargs: Any driver-specific arguments to pass to the underlying
@@ -293,7 +315,7 @@ async def connect_async(
293315 ValueError: Connection attempt with built-in database authentication
294316 and then subsequent attempt with IAM database authentication.
295317 KeyError: Unsupported database driver Must be one of pymysql, asyncpg,
296- pg8000, psycopg , and pytds.
318+ pg8000, local_unix_socket , and pytds.
297319 RuntimeError: Connector has been closed. Cannot connect using a closed
298320 Connector.
299321 """
@@ -362,7 +384,7 @@ async def connect_async(
362384 connect_func = {
363385 "pymysql" : pymysql .connect ,
364386 "pg8000" : pg8000 .connect ,
365- "psycopg " : psycopg .connect ,
387+ "local_unix_socket " : local_unix_socket .connect ,
366388 "asyncpg" : asyncpg .connect ,
367389 "pytds" : pytds .connect ,
368390 }
@@ -449,17 +471,6 @@ async def connect_async(
449471 server_hostname = ip_address ,
450472 )
451473
452- host = ip_address
453- # start local proxy if driver needs it
454- if driver in LOCAL_PROXY_DRIVERS :
455- local_socket_path = kwargs .pop ("local_socket_path" , "/tmp/connector-socket" )
456- host = local_socket_path
457- self ._proxy = proxy .start_local_proxy (
458- sock ,
459- socket_path = f"{ local_socket_path } /.s.PGSQL.{ SERVER_PROXY_PORT } " ,
460- loop = self ._loop
461- )
462-
463474 # If this connection was opened using a domain name, then store it
464475 # for later in case we need to forcibly close it on failover.
465476 if conn_info .conn_name .domain_name :
@@ -543,6 +554,7 @@ async def close_async(self) -> None:
543554 await self ._client .close ()
544555 await asyncio .gather (* [cache .close () for cache in self ._cache .values ()])
545556
557+
546558async def create_async_connector (
547559 ip_type : str | IPTypes = IPTypes .PUBLIC ,
548560 enable_iam_auth : bool = False ,
0 commit comments