diff --git a/airflow/providers/amazon/aws/hooks/rds.py b/airflow/providers/amazon/aws/hooks/rds.py new file mode 100644 index 0000000000000..3539e951cade6 --- /dev/null +++ b/airflow/providers/amazon/aws/hooks/rds.py @@ -0,0 +1,59 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Interact with AWS RDS.""" + +from typing import TYPE_CHECKING + +from airflow.providers.amazon.aws.hooks.base_aws import AwsBaseHook + +if TYPE_CHECKING: + from mypy_boto3_rds import RDSClient + + +class RdsHook(AwsBaseHook): + """ + Interact with AWS RDS using proper client from the boto3 library. + + Hook attribute `conn` has all methods that listed in documentation + + .. seealso:: + - https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html + - https://docs.aws.amazon.com/rds/index.html + + Additional arguments (such as ``aws_conn_id`` or ``region_name``) may be specified and + are passed down to the underlying AwsBaseHook. + + .. seealso:: + :class:`~airflow.providers.amazon.aws.hooks.base_aws.AwsBaseHook` + + :param aws_conn_id: The Airflow connection used for AWS credentials. + """ + + def __init__(self, *args, **kwargs) -> None: + kwargs["client_type"] = "rds" + super().__init__(*args, **kwargs) + + @property + def conn(self) -> 'RDSClient': + """ + Get the underlying boto3 RDS client (cached) + + :return: boto3 RDS client + :rtype: botocore.client.RDS + """ + return super().conn diff --git a/airflow/providers/amazon/provider.yaml b/airflow/providers/amazon/provider.yaml index 962e48b10541c..e74a383f2b64c 100644 --- a/airflow/providers/amazon/provider.yaml +++ b/airflow/providers/amazon/provider.yaml @@ -103,6 +103,10 @@ integrations: external-doc-url: https://aws.amazon.com/kinesis/data-firehose/ logo: /integration-logos/aws/Amazon-Kinesis-Data-Firehose_light-bg@4x.png tags: [aws] + - integration-name: Amazon RDS + external-doc-url: https://aws.amazon.com/rds/ + logo: /integration-logos/aws/Amazon-RDS_light-bg@4x.png + tags: [aws] - integration-name: Amazon Redshift external-doc-url: https://aws.amazon.com/redshift/ logo: /integration-logos/aws/Amazon-Redshift_light-bg@4x.png @@ -382,6 +386,9 @@ hooks: - integration-name: Amazon CloudWatch Logs python-modules: - airflow.providers.amazon.aws.hooks.logs + - integration-name: Amazon RDS + python-modules: + - airflow.providers.amazon.aws.hooks.rds - integration-name: Amazon Redshift python-modules: - airflow.providers.amazon.aws.hooks.redshift diff --git a/docs/apache-airflow-providers-amazon/index.rst b/docs/apache-airflow-providers-amazon/index.rst index 7145eab6c9094..93dac67ebe52b 100644 --- a/docs/apache-airflow-providers-amazon/index.rst +++ b/docs/apache-airflow-providers-amazon/index.rst @@ -87,6 +87,7 @@ PIP package Version required ``redshift_connector`` ``~=2.0.888`` ``sqlalchemy_redshift`` ``~=0.8.6`` ``watchtower`` ``~=2.0.1`` +``mypy-boto3-rds`` ``>=1.21.0`` ======================= =================== Cross provider package dependencies diff --git a/docs/integration-logos/aws/Amazon-RDS_light-bg@4x.png b/docs/integration-logos/aws/Amazon-RDS_light-bg@4x.png new file mode 100644 index 0000000000000..cc40d95a15948 Binary files /dev/null and b/docs/integration-logos/aws/Amazon-RDS_light-bg@4x.png differ diff --git a/setup.py b/setup.py index bcdca1e131148..02d475ad877fa 100644 --- a/setup.py +++ b/setup.py @@ -202,6 +202,7 @@ def write_version(filename: str = os.path.join(*[my_dir, "airflow", "git_version 'redshift_connector>=2.0.888', 'sqlalchemy_redshift>=0.8.6', pandas_requirement, + 'mypy-boto3-rds>=1.21.0', ] apache_beam = [ 'apache-beam>=2.33.0', diff --git a/tests/providers/amazon/aws/hooks/test_rds.py b/tests/providers/amazon/aws/hooks/test_rds.py new file mode 100644 index 0000000000000..89ec78246dcb8 --- /dev/null +++ b/tests/providers/amazon/aws/hooks/test_rds.py @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from airflow.providers.amazon.aws.hooks.rds import RdsHook + + +class TestRdsHook: + def test_conn_attribute(self): + hook = RdsHook(aws_conn_id='aws_default', region_name='us-east-1') + assert hasattr(hook, 'conn') + assert hook.conn.__class__.__name__ == 'RDS'