Repository: finos/perspective
Issue: PerspectiveAIOHTTPWebsocketConnection does not set max_msg_size

## Bug Report

The `connect` method receives `max_message_size` (which is passed in as `1024*1024*1024`), but then does not set that in the `ws_connect` method, which *should* be set thus:

```
 self._ws_cm = self._session.ws_connect(url, max_msg_size=max_message_size)
```

### Steps to Reproduce:
 1. Instantiate a `PerspectiveAIOHTTPClient`, connecting to a perspective server websocket, and loading a large view (> 4194304 bytes (4MB), which is the default `max_msg_size` for an aiohttp websocket):
```
client = await aiohttp_websocket("wss://server")
table = client.open_table("my_table")
view = await table.view(columns=["col1", "col2", "col3"]
records = await view.to_records()
```

### Expected Result:
`records` is populated with the view data

### Actual Result:
The aiohttp websocket silently disconnects (which is another problem as the exception is never bubbled up) and the coroutine never seems to yield anything, with the asyncio loop seemingly stuck forever.

### Environment:
Python 3.9.13 (though python version does not really matter here)
perspective-python 1.9.4

### Additional Context:
For anyone else who experiences this, it can be gotten around in the meanwhile by monkey patching the `connect` method of `PerspectiveAIOHTTPWebsocketConnection`


Changed files:
python/perspective/perspective/client/tornado.py, python/perspective/perspective/client/aiohttp.py, python/perspective/perspective/client/websocket.py

diff --git a/python/perspective/perspective/client/aiohttp.py b/python/perspective/perspective/client/aiohttp.py
index 9a4e7f12d..17b103a47 100644
--- a/python/perspective/perspective/client/aiohttp.py
+++ b/python/perspective/perspective/client/aiohttp.py
@@ -48,8 +48,13 @@ class PerspectiveAIOHTTPWebsocketConnection(PerspectiveWebsocketConnection):
             elif msg.type == aiohttp.WSMsgType.CLOSE:
                 return
 
-    async def connect(self, url, on_message, max_message_size) -> None:
-        self._ws_cm = self._session.ws_connect(url)
+    async def connect(self, url, on_message, **websocket_connect_kwargs) -> None:
+        max_message_size = websocket_connect_kwargs.pop("max_message_size", None) or websocket_connect_kwargs.pop("max_msg_size", None) or 1024 * 1024 * 1024
+        self._ws_cm = self._session.ws_connect(
+            url,
+            max_msg_size=max_message_size,
+            **websocket_connect_kwargs,
+        )
         self._ws = await self._ws_cm.__aenter__()
         self._on_message = on_message
         self._task = asyncio.create_task(self._receive_messages())
diff --git a/python/perspective/perspective/client/tornado.py b/python/perspective/perspective/client/tornado.py
index c1dc328a4..d6311554b 100644
--- a/python/perspective/perspective/client/tornado.py
+++ b/python/perspective/perspective/client/tornado.py
@@ -35,11 +35,12 @@ class PerspectiveTornadoWebsocketConnection(PerspectiveWebsocketConnection):
     def __init__(self):
         self._ws = None
 
-    async def connect(self, url, on_message, max_message_size) -> None:
+    async def connect(self, url, on_message, **websocket_connect_kwargs) -> None:
         self._ws = await websocket_connect(
             url,
             on_message_callback=on_message,
-            max_message_size=max_message_size,
+            max_message_size=websocket_connect_kwargs.pop("max_message_size", 1024 * 1024 * 1024),
+            **websocket_connect_kwargs,
         )
 
     def periodic(self, callback, interval) -> Periodic:
diff --git a/python/perspective/perspective/client/websocket.py b/python/perspective/perspective/client/websocket.py
index 9e6ff83c5..5377b2217 100644
--- a/python/perspective/perspective/client/websocket.py
+++ b/python/perspective/perspective/client/websocket.py
@@ -65,13 +65,14 @@ class PerspectiveWebsocketClient(PerspectiveClient):
         respond with `pong`."""
         await self.send("ping")
 
-    async def connect(self, url):
+    async def connect(self, url, **websocket_connect_kwargs):
         """Connect to the remote websocket, and send the `init` message to
         assert that the Websocket is alive and accepting connections."""
         await self._websocket.connect(
             url,
             on_message=self.on_message,
-            max_message_size=1024 * 1024 * 1024,
+            max_message_size=websocket_connect_kwargs.pop("max_message_size", 1024 * 1024 * 1024),
+            **websocket_connect_kwargs,
         )
 
         await self.send({"id": -1, "cmd": "init"})