Skip to content

Add support for connector factory in connect args#1313

Open
enocom wants to merge 1 commit intoMagicStack:masterfrom
enocom:master
Open

Add support for connector factory in connect args#1313
enocom wants to merge 1 commit intoMagicStack:masterfrom
enocom:master

Conversation

@enocom
Copy link

@enocom enocom commented Mar 24, 2026

This commit adds support for providing a connector factory, a callable that provides full control over how the network connection to the PostgreSQL server is established. When specified, this factory replaces the default connection logic. The callable receives the following arguments:

  • proto_factory - a callable that returns the asyncpg protocol instance
  • host - the target hostname (positional)
  • port - the target port (positional)
  • loop - the event loop (keyword argument)
  • ssl - the SSL context, or None (keyword argument)

The callable must return an awaitable that resolves to a (transport, protocol) tuple, compatible with
asyncio.loop.create_connection.

This is useful for scenarios such as connecting through a proxy, establishing an SSH tunnel, or performing custom socket setup before the PostgreSQL protocol begins.

Usage looks like this:

async def my_connector(proto_factory, host, port, *, loop, ssl):
    tunnel_sock = await open_ssh_tunnel(host, port)
    return await loop.create_connection(
        proto_factory, sock=tunnel_sock, ssl=ssl)

conn = await asyncpg.connect(
    connector_factory=my_connector,
    host='db.example.com',
    user='postgres',
)

Fixes #1054.

This commit adds support for providing a connector factory, a callable
that provides full control over how the network connection to the
PostgreSQL server is established. When specified, this factory replaces
the default connection logic. The callable receives the following
arguments:

- *proto_factory* - a callable that returns the asyncpg protocol
  instance
- *host* - the target hostname (positional)
- *port* - the target port (positional)
- *loop* - the event loop (keyword argument)
- *ssl* - the SSL context, or ``None`` (keyword argument)

The callable must return an awaitable that resolves to a
`(transport, protocol)` tuple, compatible with
`asyncio.loop.create_connection`.

This is useful for scenarios such as connecting through a proxy,
establishing an SSH tunnel, or performing custom socket setup
before the PostgreSQL protocol begins.

Usage looks like this:

```
async def my_connector(proto_factory, host, port, *, loop, ssl):
    tunnel_sock = await open_ssh_tunnel(host, port)
    return await loop.create_connection(
        proto_factory, sock=tunnel_sock, ssl=ssl)

conn = await asyncpg.connect(
    connector_factory=my_connector,
    host='db.example.com',
    user='postgres',
)
```

Fixes MagicStack#1054.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: allow connection with pre-configured socket

1 participant