This is an automated email from the ASF dual-hosted git repository.

vincbeck pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new f9809578ba5 Add `S3TablesDeleteNamespaceOperator` (#66375)
f9809578ba5 is described below

commit f9809578ba572a0135547f9da4914399f06bc619
Author: John Jackson <[email protected]>
AuthorDate: Tue May 5 06:59:23 2026 -0700

    Add `S3TablesDeleteNamespaceOperator` (#66375)
---
 providers/amazon/docs/operators/s3_tables.rst      | 14 ++++++++++
 .../providers/amazon/aws/operators/s3_tables.py    | 32 ++++++++++++++++++++++
 .../tests/system/amazon/aws/example_s3_tables.py   | 19 +++++++------
 .../unit/amazon/aws/operators/test_s3_tables.py    | 24 ++++++++++++++++
 4 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/providers/amazon/docs/operators/s3_tables.rst 
b/providers/amazon/docs/operators/s3_tables.rst
index 207fa848bf4..7e10ec31277 100644
--- a/providers/amazon/docs/operators/s3_tables.rst
+++ b/providers/amazon/docs/operators/s3_tables.rst
@@ -61,6 +61,20 @@ To create a new Iceberg table in an Amazon S3 Tables 
namespace you can use
     :start-after: [START howto_operator_s3tables_create_table]
     :end-before: [END howto_operator_s3tables_create_table]
 
+.. _howto/operator:S3TablesDeleteNamespaceOperator:
+
+Delete a Namespace
+------------------
+
+To delete a namespace from an Amazon S3 Tables table bucket, use
+:class:`~airflow.providers.amazon.aws.operators.s3_tables.S3TablesDeleteNamespaceOperator`.
+
+.. exampleinclude:: /../../amazon/tests/system/amazon/aws/example_s3_tables.py
+    :language: python
+    :dedent: 4
+    :start-after: [START howto_operator_s3tables_delete_namespace]
+    :end-before: [END howto_operator_s3tables_delete_namespace]
+
 .. _howto/operator:S3TablesDeleteTableOperator:
 
 Delete a Table
diff --git 
a/providers/amazon/src/airflow/providers/amazon/aws/operators/s3_tables.py 
b/providers/amazon/src/airflow/providers/amazon/aws/operators/s3_tables.py
index 53dff2f1f03..2f2b15bb04e 100644
--- a/providers/amazon/src/airflow/providers/amazon/aws/operators/s3_tables.py
+++ b/providers/amazon/src/airflow/providers/amazon/aws/operators/s3_tables.py
@@ -165,6 +165,38 @@ class 
S3TablesDeleteTableOperator(AwsBaseOperator[AwsBaseHook]):
         self.log.info("Deleted table %s", self.table_name)
 
 
+class S3TablesDeleteNamespaceOperator(AwsBaseOperator[S3TablesHook]):
+    """
+    Delete a namespace from an Amazon S3 Tables table bucket.
+
+    .. seealso::
+        For more information on how to use this operator, take a look at the 
guide:
+        :ref:`howto/operator:S3TablesDeleteNamespaceOperator`
+
+    :param table_bucket_arn: The ARN of the table bucket. (templated)
+    :param namespace: The namespace to delete. (templated)
+    """
+
+    template_fields: Sequence[str] = aws_template_fields("table_bucket_arn", 
"namespace")
+    aws_hook_class = S3TablesHook
+
+    def __init__(
+        self,
+        *,
+        table_bucket_arn: str,
+        namespace: str,
+        **kwargs,
+    ) -> None:
+        super().__init__(**kwargs)
+        self.table_bucket_arn = table_bucket_arn
+        self.namespace = namespace
+
+    def execute(self, context: Context) -> None:
+        self.log.info("Deleting namespace %s from %s", self.namespace, 
self.table_bucket_arn)
+        self.hook.conn.delete_namespace(tableBucketARN=self.table_bucket_arn, 
namespace=self.namespace)
+        self.log.info("Deleted namespace %s", self.namespace)
+
+
 class S3TablesCreateTableBucketOperator(AwsBaseOperator[S3TablesHook]):
     """
     Create an Amazon S3 Tables table bucket.
diff --git a/providers/amazon/tests/system/amazon/aws/example_s3_tables.py 
b/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
index f0bba39ed28..d02705cc6ce 100644
--- a/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
+++ b/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
@@ -22,6 +22,7 @@ from airflow.providers.amazon.aws.operators.s3_tables import (
     S3TablesCreateNamespaceOperator,
     S3TablesCreateTableBucketOperator,
     S3TablesCreateTableOperator,
+    S3TablesDeleteNamespaceOperator,
     S3TablesDeleteTableBucketOperator,
     S3TablesDeleteTableOperator,
 )
@@ -72,13 +73,6 @@ with DAG(
 
         
boto3.client("s3tables").create_namespace(tableBucketARN=table_bucket_arn, 
namespace=[namespace])
 
-    @task(trigger_rule=TriggerRule.ALL_DONE)
-    def delete_namespace(table_bucket_arn: str, namespace: str):
-        """Delete the namespace."""
-        import boto3
-
-        
boto3.client("s3tables").delete_namespace(tableBucketARN=table_bucket_arn, 
namespace=namespace)
-
     # [START howto_operator_s3tables_create_table_bucket]
     create_table_bucket = S3TablesCreateTableBucketOperator(
         task_id="create_table_bucket",
@@ -121,6 +115,15 @@ with DAG(
     )
     # [END howto_operator_s3tables_delete_table_bucket]
 
+    # [START howto_operator_s3tables_delete_namespace]
+    delete_namespace = S3TablesDeleteNamespaceOperator(
+        task_id="delete_namespace",
+        table_bucket_arn=create_table_bucket.output,
+        namespace=namespace,
+        trigger_rule=TriggerRule.ALL_DONE,
+    )
+    # [END howto_operator_s3tables_delete_namespace]
+
     chain(
         # TEST SETUP
         test_context,
@@ -130,7 +133,7 @@ with DAG(
         create_table,
         # TEST TEARDOWN
         delete_table,
-        delete_namespace(table_bucket_arn=create_table_bucket.output, 
namespace=namespace),
+        delete_namespace,
         delete_table_bucket,
     )
 
diff --git a/providers/amazon/tests/unit/amazon/aws/operators/test_s3_tables.py 
b/providers/amazon/tests/unit/amazon/aws/operators/test_s3_tables.py
index e9b3bf714f6..7943e69f906 100644
--- a/providers/amazon/tests/unit/amazon/aws/operators/test_s3_tables.py
+++ b/providers/amazon/tests/unit/amazon/aws/operators/test_s3_tables.py
@@ -28,6 +28,7 @@ from airflow.providers.amazon.aws.operators.s3_tables import (
     S3TablesCreateNamespaceOperator,
     S3TablesCreateTableBucketOperator,
     S3TablesCreateTableOperator,
+    S3TablesDeleteNamespaceOperator,
     S3TablesDeleteTableBucketOperator,
     S3TablesDeleteTableOperator,
 )
@@ -289,3 +290,26 @@ class TestS3TablesCreateNamespaceOperator:
 
     def test_template_fields(self):
         validate_template_fields(self.operator)
+
+
+class TestS3TablesDeleteNamespaceOperator:
+    def setup_method(self):
+        self.operator = S3TablesDeleteNamespaceOperator(
+            task_id="delete_namespace",
+            table_bucket_arn=TABLE_BUCKET_ARN,
+            namespace=NAMESPACE,
+        )
+
+    @mock.patch.object(S3TablesHook, "conn", new_callable=mock.PropertyMock)
+    def test_execute(self, mock_conn):
+        mock_client = mock.MagicMock()
+        mock_conn.return_value = mock_client
+
+        self.operator.execute({})
+
+        mock_client.delete_namespace.assert_called_once_with(
+            tableBucketARN=TABLE_BUCKET_ARN, namespace=NAMESPACE
+        )
+
+    def test_template_fields(self):
+        validate_template_fields(self.operator)

Reply via email to