From c433d6758ea77b6e0a407c781de9d974a214863b Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:03:09 -0700 Subject: [PATCH 1/7] docs: correct the MySQL Global Database plugin chain --- docs/using-the-python-wrapper/GlobalDatabases.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/using-the-python-wrapper/GlobalDatabases.md b/docs/using-the-python-wrapper/GlobalDatabases.md index dc0c9baef..179b1ba9d 100644 --- a/docs/using-the-python-wrapper/GlobalDatabases.md +++ b/docs/using-the-python-wrapper/GlobalDatabases.md @@ -32,6 +32,14 @@ Use the global cluster endpoint: > **Note:** Add additional plugins as needed for your use case. +> **Warning:** The plugin lists above include `host_monitoring_v2`, which requires a driver that +> supports aborting a connection from a separate thread. The MySQL Connector/Python driver does not, +> so **omit `host_monitoring_v2` when connecting to Aurora MySQL with `mysql-connector-python`** — +> loading it raises `Aborting connections from a separate thread is not supported for the detected +> driver dialect` and the connection never opens. The asynchronous MySQL driver (`aiomysql`) does +> support it. See [Host Monitoring Plugin](./using-plugins/UsingTheHostMonitoringPlugin.md) and the +> [plugin compatibility matrix](./PluginChainCompatibility.md). + ### Reader Connections **Connection String:** @@ -53,6 +61,9 @@ Use the cluster reader endpoint: > **Note:** Add additional plugins as needed for your use case. +> **Warning:** As with writer connections, omit `host_monitoring_v2` when connecting to Aurora MySQL +> with `mysql-connector-python`. See the warning under [Writer Connections](#writer-connections). + ## Example Configuration ### PostgreSQL Example @@ -101,7 +112,9 @@ from mysql.connector import Connect with AwsWrapperConnection.connect( Connect, "host=my-global-db.global-xyz.global.rds.amazonaws.com database=mydb user=admin password=pwd", - plugins="initial_connection,failover_v2,host_monitoring_v2", + # host_monitoring_v2 is intentionally absent: mysql-connector-python cannot abort a + # connection from a separate thread, so the plugin refuses to load on this driver. + plugins="initial_connection,failover_v2", wrapper_dialect="global-aurora-mysql", cluster_id="1", global_cluster_instance_host_patterns="us-east-1:?.abc123.us-east-1.rds.amazonaws.com,us-west-2:?.def456.us-west-2.rds.amazonaws.com", From 8d5b36de264a0381f4afd1c564c17966aa01ff3f Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:42:54 -0700 Subject: [PATCH 2/7] fix: pin the async Aurora PostgreSQL topology query to pg_catalog --- .../aio/host_list_provider.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/aws_advanced_python_wrapper/aio/host_list_provider.py b/aws_advanced_python_wrapper/aio/host_list_provider.py index 240b6bea1..38345699c 100644 --- a/aws_advanced_python_wrapper/aio/host_list_provider.py +++ b/aws_advanced_python_wrapper/aio/host_list_provider.py @@ -172,12 +172,14 @@ async def stop(self) -> None: class AsyncAuroraHostListProvider: """Aurora topology discovery over an async driver connection. - Runs an Aurora-topology query (e.g., ``SELECT server_id, - session_id = 'MASTER_SESSION_ID' AS is_writer, ... FROM - aurora_replica_status``) and returns a tuple of :class:`HostInfo` - objects. The exact SQL and parsing live on the shared sync + Runs an Aurora-topology query (e.g., ``SELECT server_id, session_id + OPERATOR(pg_catalog.=) 'MASTER_SESSION_ID' AS is_writer, ... FROM + pg_catalog.aurora_replica_status()``) and returns a tuple of + :class:`HostInfo` objects. The exact SQL and parsing live on the shared sync :class:`TopologyAwareDatabaseDialect` classes (reused rather than - duplicated). + duplicated). Note the schema qualification: every function and operator in a + PostgreSQL query the driver issues internally is pinned to ``pg_catalog`` so + the session's ``search_path`` cannot redirect it. Refresh flow (N.1b, matches sync RdsHostListProvider -> ClusterTopologyMonitor): @@ -199,10 +201,13 @@ def __init__( props: Properties, driver_dialect: AsyncDriverDialect, topology_query: str = ( - "SELECT SERVER_ID, SESSION_ID = 'MASTER_SESSION_ID' AS IS_WRITER " - "FROM aurora_replica_status() " - "WHERE EXTRACT(EPOCH FROM (NOW() - LAST_UPDATE_TIMESTAMP)) <= 300 " - "OR SESSION_ID = 'MASTER_SESSION_ID' " + "SELECT SERVER_ID, " + "SESSION_ID OPERATOR(pg_catalog.=) 'MASTER_SESSION_ID' AS IS_WRITER " + "FROM pg_catalog.aurora_replica_status() " + "WHERE EXTRACT(EPOCH FROM (pg_catalog.NOW() " + "OPERATOR(pg_catalog.-) LAST_UPDATE_TIMESTAMP)) " + "OPERATOR(pg_catalog.<=) 300 " + "OR SESSION_ID OPERATOR(pg_catalog.=) 'MASTER_SESSION_ID' " # A reader whose replica status hasn't reported yet has a NULL # LAST_UPDATE_TIMESTAMP -- the freshness check above is NULL # (not TRUE) for it, so without this clause every such reader is @@ -210,7 +215,7 @@ def __init__( # host list is then stranded at one host and a writer outage # yields FailoverFailedError (fail_from_reader_to_writer, # failover_with_iam, failover_with_secrets_manager). Mirrors the - # sync Aurora-PG topology query (database_dialect.py:505-511). + # sync Aurora-PG topology query. "OR LAST_UPDATE_TIMESTAMP IS NULL" ), cluster_id: Optional[str] = None, From c8361f273e69accd95422277465419783f3ee81a Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:49:01 -0700 Subject: [PATCH 3/7] fix: mask every credential-bearing property, not only 'password' --- .../utils/properties.py | 12 ++++++-- tests/unit/test_properties_utils.py | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/aws_advanced_python_wrapper/utils/properties.py b/aws_advanced_python_wrapper/utils/properties.py index ef144e33b..2dc524fa2 100644 --- a/aws_advanced_python_wrapper/utils/properties.py +++ b/aws_advanced_python_wrapper/utils/properties.py @@ -913,11 +913,19 @@ def log_properties(props: Properties): return f"\n{props}" + _SECRET_NAME_MARKERS = ("password", "passwd") + + @staticmethod + def _is_secret_property(key: str) -> bool: + lowered = key.lower() + return any(marker in lowered for marker in PropertiesUtils._SECRET_NAME_MARKERS) + @staticmethod def mask_properties(props: Properties) -> Properties: masked_properties = Properties(props.copy()) - if WrapperProperties.PASSWORD.name in masked_properties: - masked_properties[WrapperProperties.PASSWORD.name] = "***" + for key in masked_properties: + if PropertiesUtils._is_secret_property(key): + masked_properties[key] = "***" return masked_properties diff --git a/tests/unit/test_properties_utils.py b/tests/unit/test_properties_utils.py index 3834352e8..5d56a95d7 100644 --- a/tests/unit/test_properties_utils.py +++ b/tests/unit/test_properties_utils.py @@ -83,6 +83,35 @@ def test_masked_props(expected, test_props): assert expected == props_copy +@pytest.mark.parametrize("key", [ + "password", + "idp_password", # documented as required for federated auth + "monitoring-password", # forwarded to internal monitoring connections + "blue-green-monitoring-password", + "sslpassword", # driver-defined, never in WrapperProperties + "PASSWORD", # matching must not be case sensitive +]) +def test_masked_props_covers_every_credential_bearing_key(key): + """Regression: only 'password' was masked, so every other credential-bearing + property was written to the log in cleartext on connect.""" + masked = PropertiesUtils.mask_properties(Properties({"user": "postgres", key: "s3cret"})) + assert masked[key] == "***" + assert masked["user"] == "postgres" + + +@pytest.mark.parametrize("key", [ + "secrets_manager_secret_id", + "secrets_manager_region", + "secrets_manager_endpoint", + "iam_token_expiration", +]) +def test_masked_props_keeps_non_secret_metadata_readable(key): + """These name or locate a secret but are not themselves credentials; masking + them would remove what is needed to diagnose a misconfigured secret.""" + masked = PropertiesUtils.mask_properties(Properties({key: "visible-value"})) + assert masked[key] == "visible-value" + + @pytest.mark.parametrize("expected, test_props", [pytest.param(Properties({"user": "postgres", "test_property": 1}), From 16b7e49f0ac3e3a922656be857b4a7f0ab02f938 Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:54:12 -0700 Subject: [PATCH 4/7] docs: correct plugin codes and the dialect property name --- docs/using-the-python-wrapper/PluginChainCompatibility.md | 2 +- docs/using-the-python-wrapper/UsingThePythonWrapper.md | 2 +- .../using-plugins/UsingGlobalAuroraAccessibleRegions.md | 2 +- .../using-plugins/UsingMonitoringConnectionPriority.md | 4 ++-- .../using-plugins/UsingTheDeveloperPlugin.md | 4 ++-- .../using-plugins/UsingTheGdbFailoverPlugin.md | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/using-the-python-wrapper/PluginChainCompatibility.md b/docs/using-the-python-wrapper/PluginChainCompatibility.md index f41694c9a..02b543843 100644 --- a/docs/using-the-python-wrapper/PluginChainCompatibility.md +++ b/docs/using-the-python-wrapper/PluginChainCompatibility.md @@ -22,7 +22,7 @@ a chain you haven't used before. |------------------------------|------------------------------------------------|-----| | `host_monitoring` (EFM v1) | sync MySQL (`mysql-connector-python`) | EFM requires a thread-based connection abort that `mysql-connector-python` doesn't expose. Symptoms: monitor threads hang on shutdown, "Python hangs on exit" when a host is unreachable. Use the chain **without EFM**, or switch to the async driver (`aiomysql`). | | `host_monitoring_v2` (EFM v2) | sync MySQL (`mysql-connector-python`) | Same root cause as v1 — EFM v2 still depends on thread-based abort. | -| `iam_authentication` | MySQL `use_pure=True` (pure-Python connector) | The pure-Python connector truncates passwords at 255 chars; IAM tokens are typically longer. Expect `int1store requires 0 <= i <= 255` or `struct.error: ubyte format requires 0 <= number <= 255`. See README "Known Limitations". | +| `iam` | MySQL `use_pure=True` (pure-Python connector) | The pure-Python connector truncates passwords at 255 chars; IAM tokens are typically longer. Expect `int1store requires 0 <= i <= 255` or `struct.error: ubyte format requires 0 <= number <= 255`. See README "Known Limitations". | ## Recommended canonical chains diff --git a/docs/using-the-python-wrapper/UsingThePythonWrapper.md b/docs/using-the-python-wrapper/UsingThePythonWrapper.md index 834df1e23..384dc1fb5 100644 --- a/docs/using-the-python-wrapper/UsingThePythonWrapper.md +++ b/docs/using-the-python-wrapper/UsingThePythonWrapper.md @@ -98,7 +98,7 @@ The AWS Advanced Python Wrapper has several built-in plugins that are available | [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md) | `aws_secrets_manager` | Any database | Enables fetching database credentials from the AWS Secrets Manager service. | [Boto3 - AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) and [valid AWS credentials](./AwsCredentials.md) | | [Federated Authentication Plugin](./using-plugins/UsingTheFederatedAuthenticationPlugin.md) | `federated_auth` | Any database | Enables users to authenticate via Federated Identity and then database access via IAM. | [Boto3 - AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) and [valid AWS credentials](./AwsCredentials.md) | | [Okta Authentication Plugin](./using-plugins/UsingTheOktaAuthenticationPlugin.md) | `okta` | Aurora, RDS Multi-AZ DB Cluster | Enables users to authenticate using Federated Identity and then connect to their Amazon Aurora Cluster using AWS Identity and Access Management (IAM). | [Boto3 - AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) and [valid AWS credentials](./AwsCredentials.md) | -| [Custom Endpoint Plugin](./using-plugins/UsingTheCustomEndpointPlugin.md) | `customEndpoint` | Aurora,
RDS Instance | Enables custom endpoint support. | [Boto3 - AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) and [valid AWS credentials](./AwsCredentials.md) | +| [Custom Endpoint Plugin](./using-plugins/UsingTheCustomEndpointPlugin.md) | `custom_endpoint` | Aurora,
RDS Instance | Enables custom endpoint support. | [Boto3 - AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) and [valid AWS credentials](./AwsCredentials.md) | | Aurora Stale DNS Plugin | `stale_dns` | Aurora | Prevents incorrectly opening a new connection to an old writer host when DNS records have not yet updated after a recent failover event.

:warning:**Note:** Contrary to `failover` plugin, `stale_dns` plugin doesn't implement failover support itself. It helps to eliminate opening wrong connections to an old writer host after cluster failover is completed.

:warning:**Note:** This logic is already included in `failover` plugin so you can omit using both plugins at the same time. | None | | [Aurora Connection Tracker Plugin](./using-plugins/UsingTheAuroraConnectionTrackerPlugin.md) | `aurora_connection_tracker` | Aurora | Tracks all the opened connections. In the event of a cluster failover, the plugin will close all the impacted connections to the host. This plugin is enabled by default. | None | | [Read Write Splitting Plugin](./using-plugins/UsingTheReadWriteSplittingPlugin.md) | `read_write_splitting` | Aurora | Enables read write splitting functionality where users can switch between database reader and writer instances. | None | diff --git a/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md b/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md index b8e6a9f11..2530102f9 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md @@ -36,7 +36,7 @@ from psycopg import Connection with AwsWrapperConnection.connect( Connection.connect, "host=my-global-db.global-xyz.global.rds.amazonaws.com dbname=mydb user=admin password=pwd", - plugins="initial_connection,failover2,efm2", + plugins="initial_connection,failover_v2,host_monitoring_v2", wrapper_dialect="global-aurora-pg", cluster_id="1", global_cluster_instance_host_patterns="us-east-1:?.abc123.us-east-1.rds.amazonaws.com,us-west-2:?.def456.us-west-2.rds.amazonaws.com", diff --git a/docs/using-the-python-wrapper/using-plugins/UsingMonitoringConnectionPriority.md b/docs/using-the-python-wrapper/using-plugins/UsingMonitoringConnectionPriority.md index 8494d6096..8148fec48 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingMonitoringConnectionPriority.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingMonitoringConnectionPriority.md @@ -69,7 +69,7 @@ from psycopg import Connection with AwsWrapperConnection.connect( Connection.connect, "host=my-cluster.cluster-xyz.us-east-1.rds.amazonaws.com dbname=mydb user=admin password=pwd", - plugins="failover2,efm2", + plugins="failover_v2,host_monitoring_v2", monitoring_connection_priority="writer-or-reader", autocommit=True ) as awsconn: @@ -87,7 +87,7 @@ from psycopg import Connection with AwsWrapperConnection.connect( Connection.connect, "host=my-global-db.global-xyz.global.rds.amazonaws.com dbname=mydb user=admin password=pwd", - plugins="initial_connection,gdb_failover,efm2", + plugins="initial_connection,gdb_failover,host_monitoring_v2", wrapper_dialect="global-aurora-pg", failover_home_region="us-west-2", global_cluster_instance_host_patterns="us-east-1:?.abc123.us-east-1.rds.amazonaws.com,us-west-2:?.def456.us-west-2.rds.amazonaws.com", diff --git a/docs/using-the-python-wrapper/using-plugins/UsingTheDeveloperPlugin.md b/docs/using-the-python-wrapper/using-plugins/UsingTheDeveloperPlugin.md index 809a3db39..9dee881b8 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingTheDeveloperPlugin.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingTheDeveloperPlugin.md @@ -24,7 +24,7 @@ from aws_advanced_python_wrapper.pep249 import Error params = { "plugins": "dev", - "dialect": "aurora-pg" + "wrapper_dialect": "aurora-pg" } exception: Error = Error("test") ExceptionSimulatorManager.raise_exception_on_next_connect(exception) @@ -45,7 +45,7 @@ from aws_advanced_python_wrapper import AwsWrapperConnection params = { "plugins": "dev", - "dialect": "aurora-pg" + "wrapper_dialect": "aurora-pg" } exception: RuntimeError = RuntimeError("test") ExceptionSimulatorManager.raise_exception_on_next_method("Connection.cursor", exception) diff --git a/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md b/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md index 65f9838bf..7f4bf09b6 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md @@ -75,7 +75,7 @@ Please refer to the original [Failover Plugin](./UsingTheFailoverPlugin.md) and - `active_home_failover_mode=strict-writer` - `inactive_home_failover_mode=strict-writer` - `global_cluster_instance_host_patterns=us-east-1:?.XYZ1.us-east-1.rds.amazonaws.com,us-east-2:?.XYZ2.us-east-2.rds.amazonaws.com,us-west-1:?.XYZ3.us-west-1.rds.amazonaws.com` (replace `XYZ1`, `XYZ2`, `XYZ3` with values that correspond to your database) -- `dialect=global-aurora-mysql` (or `global-aurora-pg`) +- `wrapper_dialect=global-aurora-mysql` (or `global-aurora-pg`) - `plugins=initial_connection,gdb_failover,host_monitoring_v2` - use the Global Database endpoint in your connection string @@ -87,7 +87,7 @@ Please refer to the original [Failover Plugin](./UsingTheFailoverPlugin.md) and - `active_home_failover_mode=strict-home-reader` - `inactive_home_failover_mode=strict-home-reader` - `global_cluster_instance_host_patterns=us-east-1:?.XYZ1.us-east-1.rds.amazonaws.com,us-east-2:?.XYZ2.us-east-2.rds.amazonaws.com,us-west-1:?.XYZ3.us-west-1.rds.amazonaws.com` -- `dialect=global-aurora-mysql` (or `global-aurora-pg`) +- `wrapper_dialect=global-aurora-mysql` (or `global-aurora-pg`) - `plugins=initial_connection,gdb_failover,host_monitoring_v2` - use the cluster reader endpoint in region `us-west-1` in your connection string @@ -99,7 +99,7 @@ Please refer to the original [Failover Plugin](./UsingTheFailoverPlugin.md) and - `active_home_failover_mode=strict-writer` - `inactive_home_failover_mode=strict-any-reader` - `global_cluster_instance_host_patterns=us-east-1:?.XYZ1.us-east-1.rds.amazonaws.com,us-east-2:?.XYZ2.us-east-2.rds.amazonaws.com,us-west-1:?.XYZ3.us-west-1.rds.amazonaws.com` -- `dialect=global-aurora-mysql` (or `global-aurora-pg`) +- `wrapper_dialect=global-aurora-mysql` (or `global-aurora-pg`) - `plugins=initial_connection,gdb_failover,host_monitoring_v2` - use the cluster writer endpoint in region `us-west-1` in your connection string From 4c0561bc90611c673ddce851e1a07838c3496590 Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:57:18 -0700 Subject: [PATCH 5/7] docs: document the Windows event loop requirement for asyncio --- docs/GettingStarted.md | 24 +++++++++++++++++++ .../SqlAlchemySupport.md | 6 +++++ 2 files changed, 30 insertions(+) diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 66cfa3a1e..978a07a7d 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -43,6 +43,30 @@ Some features pull in additional packages when used with the asyncio API: - The async Federated Authentication and Okta Authentication plugins use [aiohttp](https://docs.aiohttp.org/) for their HTTP flows: `pip install aiohttp`. - Async SQLAlchemy (`create_async_engine`) requires SQLAlchemy's asyncio support, which includes `greenlet`: `pip install "sqlalchemy[asyncio]"`. +### Asyncio on Windows + +Python's default event loop on Windows is `ProactorEventLoop`, and Psycopg's async +connection refuses to run on it: + +``` +psycopg.InterfaceError: Psycopg cannot use the 'ProactorEventLoop' to run in async mode +``` + +Every async PostgreSQL connection fails at connect until a selector event loop is +selected. Do this once, before any async code runs: + +```python +import asyncio +import sys + +if sys.platform == "win32": + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) +``` + +This is a requirement of the underlying driver rather than of the wrapper, and it does +not apply on Linux or macOS, where the default loop is already a selector loop. See +[Psycopg's asynchronous operations documentation](https://www.psycopg.org/psycopg3/docs/advanced/async.html#async). + ## Using the AWS Advanced Python Wrapper To start using the wrapper with Psycopg, you need to pass Psycopg's connect function to the `AwsWrapperConnection#connect` method as shown in the following example: diff --git a/docs/using-the-python-wrapper/SqlAlchemySupport.md b/docs/using-the-python-wrapper/SqlAlchemySupport.md index 233d0c669..124b7e26c 100644 --- a/docs/using-the-python-wrapper/SqlAlchemySupport.md +++ b/docs/using-the-python-wrapper/SqlAlchemySupport.md @@ -172,6 +172,12 @@ Read/write splitting is **not** supported with SQLAlchemy: the plugins switch in > [!NOTE]\ > Async engines require SQLAlchemy's asyncio support (`pip install "sqlalchemy[asyncio]"`, which includes `greenlet`), plus the async driver: Psycopg for PostgreSQL, [aiomysql](https://github.com/aio-libs/aiomysql) for MySQL. +> [!IMPORTANT]\ +> **On Windows**, select a selector event loop before running any async code, or every +> async PostgreSQL connection fails with `Psycopg cannot use the 'ProactorEventLoop' to +> run in async mode` — `ProactorEventLoop` is Python's default there. See +> [Asyncio on Windows](../GettingStarted.md#asyncio-on-windows). + The wrapper exposes a native async path. `create_async_engine` works with the URL-based dialect: ```python From 38eb22d322e2fe076ea64792448d1e826a56d3c9 Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:58:10 -0700 Subject: [PATCH 6/7] docs: scope gdb_accessible_regions to the synchronous driver --- .../using-plugins/UsingGlobalAuroraAccessibleRegions.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md b/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md index 2530102f9..13a2c04de 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingGlobalAuroraAccessibleRegions.md @@ -2,6 +2,9 @@ When using [Aurora Global Databases](../GlobalDatabases.md), an application may only be able to reach a subset of the regions the global cluster spans (for example, because of network routing, VPC peering, or security constraints). The `gdb_accessible_regions` property restricts the AWS Advanced Python Wrapper to a set of reachable AWS regions, excluding hosts in all other regions from host selection. +> [!IMPORTANT]\ +> **Currently supported in the synchronous wrapper only.** + ## `gdb_accessible_regions` | Property | Value | Default | @@ -25,7 +28,7 @@ The accessible-regions filter is applied **before** all other selection logic ### Fail-loud, not silent fallback -Consistent with the [AWS Advanced Python Wrapper](https://github.com/aws/aws-advanced-python-wrapper), the filter is a **hard restriction**. When the writer is in an inaccessible region, the wrapper raises an error rather than silently connecting to an unreachable or unintended host. When reader filtering leaves no candidates in accessible regions, the wrapper does **not** fall back to the unfiltered host list. +The filter is a **hard restriction**. When the writer is in an inaccessible region, the wrapper raises an error rather than silently connecting to an unreachable or unintended host. When reader filtering leaves no candidates in accessible regions, the wrapper does **not** fall back to the unfiltered host list. ## Example From 4d0cfc6ae24746cb154f965e4f0f51235de6c368 Mon Sep 17 00:00:00 2001 From: karezche <64801825+karenc-bq@users.noreply.github.com> Date: Thu, 20 Aug 2026 17:22:27 -0700 Subject: [PATCH 7/7] docs: note that host_monitoring_v2 must be removed for Aurora MySQL --- .../using-plugins/UsingTheGdbFailoverPlugin.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md b/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md index 7f4bf09b6..038dcfe87 100644 --- a/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md +++ b/docs/using-the-python-wrapper/using-plugins/UsingTheGdbFailoverPlugin.md @@ -67,6 +67,15 @@ Please refer to the original [Failover Plugin](./UsingTheFailoverPlugin.md) and ### Failover Configuration Examples +> [!IMPORTANT]\ +> The examples below list `host_monitoring_v2` in `plugins`. **Remove it when connecting to Aurora +> MySQL with `mysql-connector-python`** (`wrapper_dialect=global-aurora-mysql`): that driver cannot +> abort a connection from a separate thread, which the plugin requires, so loading it fails the +> connection with `Aborting connections from a separate thread is not supported for the detected +> driver dialect`. The asynchronous MySQL driver (`aiomysql`) does support it. See +> [Host Monitoring Plugin](./UsingTheHostMonitoringPlugin.md) and the +> [plugin compatibility matrix](../PluginChainCompatibility.md). + #### Configuration Example 1 **Goal:** Provide a user application with a writer connection. The application is deployed in the `us-west-1` region and connects to a Global Database with the `us-east-1`, `us-east-2`, and `us-west-1` regions.