apache-airflow-providers-amazon 8.25.0rc1__py3-none-any.whl → 8.26.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airflow/providers/amazon/__init__.py +1 -1
- airflow/providers/amazon/aws/hooks/athena.py +18 -9
- airflow/providers/amazon/aws/hooks/athena_sql.py +2 -1
- airflow/providers/amazon/aws/hooks/base_aws.py +34 -10
- airflow/providers/amazon/aws/hooks/chime.py +2 -1
- airflow/providers/amazon/aws/hooks/datasync.py +6 -3
- airflow/providers/amazon/aws/hooks/ecr.py +2 -1
- airflow/providers/amazon/aws/hooks/ecs.py +12 -6
- airflow/providers/amazon/aws/hooks/glacier.py +8 -4
- airflow/providers/amazon/aws/hooks/kinesis.py +2 -1
- airflow/providers/amazon/aws/hooks/logs.py +4 -2
- airflow/providers/amazon/aws/hooks/redshift_cluster.py +24 -12
- airflow/providers/amazon/aws/hooks/redshift_data.py +4 -2
- airflow/providers/amazon/aws/hooks/redshift_sql.py +6 -3
- airflow/providers/amazon/aws/hooks/s3.py +70 -53
- airflow/providers/amazon/aws/hooks/sagemaker.py +82 -41
- airflow/providers/amazon/aws/hooks/secrets_manager.py +6 -3
- airflow/providers/amazon/aws/hooks/sts.py +2 -1
- airflow/providers/amazon/aws/operators/athena.py +21 -8
- airflow/providers/amazon/aws/operators/batch.py +12 -6
- airflow/providers/amazon/aws/operators/datasync.py +2 -1
- airflow/providers/amazon/aws/operators/ecs.py +1 -0
- airflow/providers/amazon/aws/operators/emr.py +6 -86
- airflow/providers/amazon/aws/operators/glue.py +4 -2
- airflow/providers/amazon/aws/operators/glue_crawler.py +22 -19
- airflow/providers/amazon/aws/operators/neptune.py +2 -1
- airflow/providers/amazon/aws/operators/redshift_cluster.py +2 -1
- airflow/providers/amazon/aws/operators/sagemaker.py +2 -1
- airflow/providers/amazon/aws/sensors/base_aws.py +2 -1
- airflow/providers/amazon/aws/sensors/glue_catalog_partition.py +25 -17
- airflow/providers/amazon/aws/sensors/glue_crawler.py +16 -12
- airflow/providers/amazon/aws/transfers/mongo_to_s3.py +6 -3
- airflow/providers/amazon/aws/transfers/s3_to_dynamodb.py +2 -1
- airflow/providers/amazon/aws/transfers/s3_to_sql.py +2 -1
- airflow/providers/amazon/aws/triggers/ecs.py +3 -1
- airflow/providers/amazon/aws/triggers/glue.py +15 -3
- airflow/providers/amazon/aws/triggers/glue_crawler.py +8 -1
- airflow/providers/amazon/aws/utils/connection_wrapper.py +10 -5
- airflow/providers/amazon/aws/utils/mixins.py +2 -1
- airflow/providers/amazon/aws/utils/redshift.py +2 -1
- airflow/providers/amazon/get_provider_info.py +2 -1
- {apache_airflow_providers_amazon-8.25.0rc1.dist-info → apache_airflow_providers_amazon-8.26.0rc1.dist-info}/METADATA +6 -6
- {apache_airflow_providers_amazon-8.25.0rc1.dist-info → apache_airflow_providers_amazon-8.26.0rc1.dist-info}/RECORD +45 -45
- {apache_airflow_providers_amazon-8.25.0rc1.dist-info → apache_airflow_providers_amazon-8.26.0rc1.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_amazon-8.25.0rc1.dist-info → apache_airflow_providers_amazon-8.26.0rc1.dist-info}/entry_points.txt +0 -0
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
29
29
|
|
30
30
|
__all__ = ["__version__"]
|
31
31
|
|
32
|
-
__version__ = "8.
|
32
|
+
__version__ = "8.26.0"
|
33
33
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
35
35
|
"2.7.0"
|
@@ -50,7 +50,8 @@ def query_params_to_string(params: dict[str, str | Collection[str]]) -> str:
|
|
50
50
|
|
51
51
|
|
52
52
|
class AthenaHook(AwsBaseHook):
|
53
|
-
"""
|
53
|
+
"""
|
54
|
+
Interact with Amazon Athena.
|
54
55
|
|
55
56
|
Provide thick wrapper around
|
56
57
|
:external+boto3:py:class:`boto3.client("athena") <Athena.Client>`.
|
@@ -106,7 +107,8 @@ class AthenaHook(AwsBaseHook):
|
|
106
107
|
client_request_token: str | None = None,
|
107
108
|
workgroup: str = "primary",
|
108
109
|
) -> str:
|
109
|
-
"""
|
110
|
+
"""
|
111
|
+
Run a Trino/Presto query on Athena with provided config.
|
110
112
|
|
111
113
|
.. seealso::
|
112
114
|
- :external+boto3:py:meth:`Athena.Client.start_query_execution`
|
@@ -136,7 +138,8 @@ class AthenaHook(AwsBaseHook):
|
|
136
138
|
return query_execution_id
|
137
139
|
|
138
140
|
def get_query_info(self, query_execution_id: str, use_cache: bool = False) -> dict:
|
139
|
-
"""
|
141
|
+
"""
|
142
|
+
Get information about a single execution of a query.
|
140
143
|
|
141
144
|
.. seealso::
|
142
145
|
- :external+boto3:py:meth:`Athena.Client.get_query_execution`
|
@@ -152,7 +155,8 @@ class AthenaHook(AwsBaseHook):
|
|
152
155
|
return response
|
153
156
|
|
154
157
|
def check_query_status(self, query_execution_id: str, use_cache: bool = False) -> str | None:
|
155
|
-
"""
|
158
|
+
"""
|
159
|
+
Fetch the state of a submitted query.
|
156
160
|
|
157
161
|
.. seealso::
|
158
162
|
- :external+boto3:py:meth:`Athena.Client.get_query_execution`
|
@@ -200,7 +204,8 @@ class AthenaHook(AwsBaseHook):
|
|
200
204
|
def get_query_results(
|
201
205
|
self, query_execution_id: str, next_token_id: str | None = None, max_results: int = 1000
|
202
206
|
) -> dict | None:
|
203
|
-
"""
|
207
|
+
"""
|
208
|
+
Fetch submitted query results.
|
204
209
|
|
205
210
|
.. seealso::
|
206
211
|
- :external+boto3:py:meth:`Athena.Client.get_query_results`
|
@@ -234,7 +239,8 @@ class AthenaHook(AwsBaseHook):
|
|
234
239
|
page_size: int | None = None,
|
235
240
|
starting_token: str | None = None,
|
236
241
|
) -> PageIterator | None:
|
237
|
-
"""
|
242
|
+
"""
|
243
|
+
Fetch submitted Athena query results.
|
238
244
|
|
239
245
|
.. seealso::
|
240
246
|
- :external+boto3:py:class:`Athena.Paginator.GetQueryResults`
|
@@ -274,7 +280,8 @@ class AthenaHook(AwsBaseHook):
|
|
274
280
|
def poll_query_status(
|
275
281
|
self, query_execution_id: str, max_polling_attempts: int | None = None, sleep_time: int | None = None
|
276
282
|
) -> str | None:
|
277
|
-
"""
|
283
|
+
"""
|
284
|
+
Poll the state of a submitted query until it reaches final state.
|
278
285
|
|
279
286
|
:param query_execution_id: ID of submitted athena query
|
280
287
|
:param max_polling_attempts: Number of times to poll for query state before function exits
|
@@ -299,7 +306,8 @@ class AthenaHook(AwsBaseHook):
|
|
299
306
|
return self.check_query_status(query_execution_id)
|
300
307
|
|
301
308
|
def get_output_location(self, query_execution_id: str) -> str:
|
302
|
-
"""
|
309
|
+
"""
|
310
|
+
Get the output location of the query results in S3 URI format.
|
303
311
|
|
304
312
|
.. seealso::
|
305
313
|
- :external+boto3:py:meth:`Athena.Client.get_query_execution`
|
@@ -319,7 +327,8 @@ class AthenaHook(AwsBaseHook):
|
|
319
327
|
raise
|
320
328
|
|
321
329
|
def stop_query(self, query_execution_id: str) -> dict:
|
322
|
-
"""
|
330
|
+
"""
|
331
|
+
Cancel the submitted query.
|
323
332
|
|
324
333
|
.. seealso::
|
325
334
|
- :external+boto3:py:meth:`Athena.Client.stop_query_execution`
|
@@ -70,9 +70,23 @@ if TYPE_CHECKING:
|
|
70
70
|
|
71
71
|
from airflow.models.connection import Connection # Avoid circular imports.
|
72
72
|
|
73
|
+
_loader = botocore.loaders.Loader()
|
74
|
+
"""
|
75
|
+
botocore data loader to be used with async sessions
|
76
|
+
|
77
|
+
By default, a botocore session creates and caches an instance of JSONDecoder which
|
78
|
+
consumes a lot of memory. This issue was reported here https://github.com/boto/botocore/issues/3078.
|
79
|
+
In the context of triggers which use boto sessions, this can result in excessive
|
80
|
+
memory usage and as a result reduced capacity on the triggerer. We can reduce
|
81
|
+
memory footprint by sharing the loader instance across the sessions.
|
82
|
+
|
83
|
+
:meta private:
|
84
|
+
"""
|
85
|
+
|
73
86
|
|
74
87
|
class BaseSessionFactory(LoggingMixin):
|
75
|
-
"""
|
88
|
+
"""
|
89
|
+
Base AWS Session Factory class.
|
76
90
|
|
77
91
|
This handles synchronous and async boto session creation. It can handle most
|
78
92
|
of the AWS supported authentication methods.
|
@@ -154,7 +168,9 @@ class BaseSessionFactory(LoggingMixin):
|
|
154
168
|
def get_async_session(self):
|
155
169
|
from aiobotocore.session import get_session as async_get_session
|
156
170
|
|
157
|
-
|
171
|
+
session = async_get_session()
|
172
|
+
session.register_component("data_loader", _loader)
|
173
|
+
return session
|
158
174
|
|
159
175
|
def create_session(
|
160
176
|
self, deferrable: bool = False
|
@@ -435,7 +451,8 @@ class BaseSessionFactory(LoggingMixin):
|
|
435
451
|
|
436
452
|
|
437
453
|
class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
438
|
-
"""
|
454
|
+
"""
|
455
|
+
Generic class for interact with AWS.
|
439
456
|
|
440
457
|
This class provide a thin wrapper around the boto3 Python library.
|
441
458
|
|
@@ -497,7 +514,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
497
514
|
|
498
515
|
@staticmethod
|
499
516
|
def _find_operator_class_name(target_function_name: str) -> str | None:
|
500
|
-
"""
|
517
|
+
"""
|
518
|
+
Given a frame off the stack, return the name of the class that made the call.
|
501
519
|
|
502
520
|
This method may raise a ValueError or an IndexError. The caller is
|
503
521
|
responsible with catching and handling those.
|
@@ -547,7 +565,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
547
565
|
@staticmethod
|
548
566
|
@return_on_error("00000000-0000-0000-0000-000000000000")
|
549
567
|
def _generate_dag_key() -> str:
|
550
|
-
"""
|
568
|
+
"""
|
569
|
+
Generate a DAG key.
|
551
570
|
|
552
571
|
The Object Identifier (OID) namespace is used to salt the dag_id value.
|
553
572
|
That salted value is used to generate a SHA-1 hash which, by definition,
|
@@ -783,7 +802,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
783
802
|
return creds
|
784
803
|
|
785
804
|
def expand_role(self, role: str, region_name: str | None = None) -> str:
|
786
|
-
"""
|
805
|
+
"""
|
806
|
+
Get the Amazon Resource Name (ARN) for the role.
|
787
807
|
|
788
808
|
If IAM role is already an IAM role ARN, the value is returned unchanged.
|
789
809
|
|
@@ -861,7 +881,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
861
881
|
}
|
862
882
|
|
863
883
|
def test_connection(self):
|
864
|
-
"""
|
884
|
+
"""
|
885
|
+
Test the AWS connection by call AWS STS (Security Token Service) GetCallerIdentity API.
|
865
886
|
|
866
887
|
.. seealso::
|
867
888
|
https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html
|
@@ -898,7 +919,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
898
919
|
deferrable: bool = False,
|
899
920
|
client=None,
|
900
921
|
) -> Waiter:
|
901
|
-
"""
|
922
|
+
"""
|
923
|
+
Get a waiter by name.
|
902
924
|
|
903
925
|
First checks if there is a custom waiter with the provided waiter_name and
|
904
926
|
uses that if it exists, otherwise it will check the service client for a
|
@@ -969,7 +991,8 @@ class AwsGenericHook(BaseHook, Generic[BaseAwsConnection]):
|
|
969
991
|
|
970
992
|
|
971
993
|
class AwsBaseHook(AwsGenericHook[Union[boto3.client, boto3.resource]]):
|
972
|
-
"""
|
994
|
+
"""
|
995
|
+
Base class for interact with AWS.
|
973
996
|
|
974
997
|
This class provide a thin wrapper around the boto3 Python library.
|
975
998
|
|
@@ -1128,7 +1151,8 @@ class BaseAsyncSessionFactory(BaseSessionFactory):
|
|
1128
1151
|
category=AirflowProviderDeprecationWarning,
|
1129
1152
|
)
|
1130
1153
|
class AwsBaseAsyncHook(AwsBaseHook):
|
1131
|
-
"""
|
1154
|
+
"""
|
1155
|
+
Interacts with AWS using aiobotocore asynchronously.
|
1132
1156
|
|
1133
1157
|
:param aws_conn_id: The Airflow connection used for AWS credentials.
|
1134
1158
|
If this is None or empty then the default botocore behaviour is used. If
|
@@ -30,7 +30,8 @@ from airflow.providers.http.hooks.http import HttpHook
|
|
30
30
|
|
31
31
|
|
32
32
|
class ChimeWebhookHook(HttpHook):
|
33
|
-
"""
|
33
|
+
"""
|
34
|
+
Interact with Amazon Chime Webhooks to create notifications.
|
34
35
|
|
35
36
|
.. warning:: This hook is only designed to work with web hooks and not chat bots.
|
36
37
|
|
@@ -136,7 +136,8 @@ class DataSyncHook(AwsBaseHook):
|
|
136
136
|
def create_task(
|
137
137
|
self, source_location_arn: str, destination_location_arn: str, **create_task_kwargs
|
138
138
|
) -> str:
|
139
|
-
"""
|
139
|
+
"""
|
140
|
+
Create a Task between the specified source and destination LocationArns.
|
140
141
|
|
141
142
|
.. seealso::
|
142
143
|
- :external+boto3:py:meth:`DataSync.Client.create_task`
|
@@ -155,7 +156,8 @@ class DataSyncHook(AwsBaseHook):
|
|
155
156
|
return task["TaskArn"]
|
156
157
|
|
157
158
|
def update_task(self, task_arn: str, **update_task_kwargs) -> None:
|
158
|
-
"""
|
159
|
+
"""
|
160
|
+
Update a Task.
|
159
161
|
|
160
162
|
.. seealso::
|
161
163
|
- :external+boto3:py:meth:`DataSync.Client.update_task`
|
@@ -166,7 +168,8 @@ class DataSyncHook(AwsBaseHook):
|
|
166
168
|
self.get_conn().update_task(TaskArn=task_arn, **update_task_kwargs)
|
167
169
|
|
168
170
|
def delete_task(self, task_arn: str) -> None:
|
169
|
-
"""
|
171
|
+
"""
|
172
|
+
Delete a Task.
|
170
173
|
|
171
174
|
.. seealso::
|
172
175
|
- :external+boto3:py:meth:`DataSync.Client.delete_task`
|
@@ -70,7 +70,8 @@ class EcrHook(AwsBaseHook):
|
|
70
70
|
super().__init__(**kwargs)
|
71
71
|
|
72
72
|
def get_temporary_credentials(self, registry_ids: list[str] | str | None = None) -> list[EcrCredentials]:
|
73
|
-
"""
|
73
|
+
"""
|
74
|
+
Get temporary credentials for Amazon ECR.
|
74
75
|
|
75
76
|
.. seealso::
|
76
77
|
- :external+boto3:py:meth:`ECR.Client.get_authorization_token`
|
@@ -152,42 +152,48 @@ class EcsProtocol(Protocol):
|
|
152
152
|
"""
|
153
153
|
|
154
154
|
def run_task(self, **kwargs) -> dict:
|
155
|
-
"""
|
155
|
+
"""
|
156
|
+
Run a task.
|
156
157
|
|
157
158
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.run_task
|
158
159
|
"""
|
159
160
|
...
|
160
161
|
|
161
162
|
def get_waiter(self, x: str) -> Waiter:
|
162
|
-
"""
|
163
|
+
"""
|
164
|
+
Get a waiter.
|
163
165
|
|
164
166
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.get_waiter
|
165
167
|
"""
|
166
168
|
...
|
167
169
|
|
168
170
|
def describe_tasks(self, cluster: str, tasks) -> dict:
|
169
|
-
"""
|
171
|
+
"""
|
172
|
+
Describe tasks.
|
170
173
|
|
171
174
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.describe_tasks
|
172
175
|
"""
|
173
176
|
...
|
174
177
|
|
175
178
|
def stop_task(self, cluster, task, reason: str) -> dict:
|
176
|
-
"""
|
179
|
+
"""
|
180
|
+
Stop a task.
|
177
181
|
|
178
182
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.stop_task
|
179
183
|
"""
|
180
184
|
...
|
181
185
|
|
182
186
|
def describe_task_definition(self, taskDefinition: str) -> dict:
|
183
|
-
"""
|
187
|
+
"""
|
188
|
+
Describe a task definition.
|
184
189
|
|
185
190
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.describe_task_definition
|
186
191
|
"""
|
187
192
|
...
|
188
193
|
|
189
194
|
def list_tasks(self, cluster: str, launchType: str, desiredStatus: str, family: str) -> dict:
|
190
|
-
"""
|
195
|
+
"""
|
196
|
+
List tasks.
|
191
197
|
|
192
198
|
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.list_tasks
|
193
199
|
"""
|
@@ -23,7 +23,8 @@ from airflow.providers.amazon.aws.hooks.base_aws import AwsBaseHook
|
|
23
23
|
|
24
24
|
|
25
25
|
class GlacierHook(AwsBaseHook):
|
26
|
-
"""
|
26
|
+
"""
|
27
|
+
Interact with Amazon Glacier.
|
27
28
|
|
28
29
|
This is a thin wrapper around
|
29
30
|
:external+boto3:py:class:`boto3.client("glacier") <Glacier.Client>`.
|
@@ -40,7 +41,8 @@ class GlacierHook(AwsBaseHook):
|
|
40
41
|
super().__init__(*args, **kwargs)
|
41
42
|
|
42
43
|
def retrieve_inventory(self, vault_name: str) -> dict[str, Any]:
|
43
|
-
"""
|
44
|
+
"""
|
45
|
+
Initiate an Amazon Glacier inventory-retrieval job.
|
44
46
|
|
45
47
|
.. seealso::
|
46
48
|
- :external+boto3:py:meth:`Glacier.Client.initiate_job`
|
@@ -55,7 +57,8 @@ class GlacierHook(AwsBaseHook):
|
|
55
57
|
return response
|
56
58
|
|
57
59
|
def retrieve_inventory_results(self, vault_name: str, job_id: str) -> dict[str, Any]:
|
58
|
-
"""
|
60
|
+
"""
|
61
|
+
Retrieve the results of an Amazon Glacier inventory-retrieval job.
|
59
62
|
|
60
63
|
.. seealso::
|
61
64
|
- :external+boto3:py:meth:`Glacier.Client.get_job_output`
|
@@ -68,7 +71,8 @@ class GlacierHook(AwsBaseHook):
|
|
68
71
|
return response
|
69
72
|
|
70
73
|
def describe_job(self, vault_name: str, job_id: str) -> dict[str, Any]:
|
71
|
-
"""
|
74
|
+
"""
|
75
|
+
Retrieve the status of an Amazon S3 Glacier job.
|
72
76
|
|
73
77
|
.. seealso::
|
74
78
|
- :external+boto3:py:meth:`Glacier.Client.describe_job`
|
@@ -45,7 +45,8 @@ class FirehoseHook(AwsBaseHook):
|
|
45
45
|
super().__init__(*args, **kwargs)
|
46
46
|
|
47
47
|
def put_records(self, records: Iterable):
|
48
|
-
"""
|
48
|
+
"""
|
49
|
+
Write batch records to Kinesis Firehose.
|
49
50
|
|
50
51
|
.. seealso::
|
51
52
|
- :external+boto3:py:meth:`Firehose.Client.put_record_batch`
|
@@ -158,7 +158,8 @@ class AwsLogsHook(AwsBaseHook):
|
|
158
158
|
async def describe_log_streams_async(
|
159
159
|
self, log_group: str, stream_prefix: str, order_by: str, count: int
|
160
160
|
) -> dict[str, Any] | None:
|
161
|
-
"""
|
161
|
+
"""
|
162
|
+
Async function to get the list of log streams for the specified log group.
|
162
163
|
|
163
164
|
You can list all the log streams or filter the results by prefix. You can also control
|
164
165
|
how the results are ordered.
|
@@ -193,7 +194,8 @@ class AwsLogsHook(AwsBaseHook):
|
|
193
194
|
skip: int = 0,
|
194
195
|
start_from_head: bool = True,
|
195
196
|
) -> AsyncGenerator[Any, dict[str, Any]]:
|
196
|
-
"""
|
197
|
+
"""
|
198
|
+
Yield all the available items in a single log stream.
|
197
199
|
|
198
200
|
:param log_group: The name of the log group.
|
199
201
|
:param log_stream_name: The name of the specific stream.
|
@@ -27,7 +27,8 @@ from airflow.providers.amazon.aws.hooks.base_aws import AwsBaseAsyncHook, AwsBas
|
|
27
27
|
|
28
28
|
|
29
29
|
class RedshiftHook(AwsBaseHook):
|
30
|
-
"""
|
30
|
+
"""
|
31
|
+
Interact with Amazon Redshift.
|
31
32
|
|
32
33
|
This is a thin wrapper around
|
33
34
|
:external+boto3:py:class:`boto3.client("redshift") <Redshift.Client>`.
|
@@ -53,7 +54,8 @@ class RedshiftHook(AwsBaseHook):
|
|
53
54
|
master_user_password: str,
|
54
55
|
params: dict[str, Any],
|
55
56
|
) -> dict[str, Any]:
|
56
|
-
"""
|
57
|
+
"""
|
58
|
+
Create a new cluster with the specified parameters.
|
57
59
|
|
58
60
|
.. seealso::
|
59
61
|
- :external+boto3:py:meth:`Redshift.Client.create_cluster`
|
@@ -80,7 +82,8 @@ class RedshiftHook(AwsBaseHook):
|
|
80
82
|
|
81
83
|
# TODO: Wrap create_cluster_snapshot
|
82
84
|
def cluster_status(self, cluster_identifier: str) -> str:
|
83
|
-
"""
|
85
|
+
"""
|
86
|
+
Get status of a cluster.
|
84
87
|
|
85
88
|
.. seealso::
|
86
89
|
- :external+boto3:py:meth:`Redshift.Client.describe_clusters`
|
@@ -101,7 +104,8 @@ class RedshiftHook(AwsBaseHook):
|
|
101
104
|
skip_final_cluster_snapshot: bool = True,
|
102
105
|
final_cluster_snapshot_identifier: str | None = None,
|
103
106
|
):
|
104
|
-
"""
|
107
|
+
"""
|
108
|
+
Delete a cluster and optionally create a snapshot.
|
105
109
|
|
106
110
|
.. seealso::
|
107
111
|
- :external+boto3:py:meth:`Redshift.Client.delete_cluster`
|
@@ -120,7 +124,8 @@ class RedshiftHook(AwsBaseHook):
|
|
120
124
|
return response["Cluster"] if response["Cluster"] else None
|
121
125
|
|
122
126
|
def describe_cluster_snapshots(self, cluster_identifier: str) -> list[str] | None:
|
123
|
-
"""
|
127
|
+
"""
|
128
|
+
List snapshots for a cluster.
|
124
129
|
|
125
130
|
.. seealso::
|
126
131
|
- :external+boto3:py:meth:`Redshift.Client.describe_cluster_snapshots`
|
@@ -136,7 +141,8 @@ class RedshiftHook(AwsBaseHook):
|
|
136
141
|
return snapshots
|
137
142
|
|
138
143
|
def restore_from_cluster_snapshot(self, cluster_identifier: str, snapshot_identifier: str) -> str:
|
139
|
-
"""
|
144
|
+
"""
|
145
|
+
Restore a cluster from its snapshot.
|
140
146
|
|
141
147
|
.. seealso::
|
142
148
|
- :external+boto3:py:meth:`Redshift.Client.restore_from_cluster_snapshot`
|
@@ -156,7 +162,8 @@ class RedshiftHook(AwsBaseHook):
|
|
156
162
|
retention_period: int = -1,
|
157
163
|
tags: list[Any] | None = None,
|
158
164
|
) -> str:
|
159
|
-
"""
|
165
|
+
"""
|
166
|
+
Create a snapshot of a cluster.
|
160
167
|
|
161
168
|
.. seealso::
|
162
169
|
- :external+boto3:py:meth:`Redshift.Client.create_cluster_snapshot`
|
@@ -178,7 +185,8 @@ class RedshiftHook(AwsBaseHook):
|
|
178
185
|
return response["Snapshot"] if response["Snapshot"] else None
|
179
186
|
|
180
187
|
def get_cluster_snapshot_status(self, snapshot_identifier: str):
|
181
|
-
"""
|
188
|
+
"""
|
189
|
+
Get Redshift cluster snapshot status.
|
182
190
|
|
183
191
|
If cluster snapshot not found, *None* is returned.
|
184
192
|
|
@@ -210,7 +218,8 @@ class RedshiftAsyncHook(AwsBaseAsyncHook):
|
|
210
218
|
super().__init__(*args, **kwargs)
|
211
219
|
|
212
220
|
async def cluster_status(self, cluster_identifier: str, delete_operation: bool = False) -> dict[str, Any]:
|
213
|
-
"""
|
221
|
+
"""
|
222
|
+
Get the cluster status.
|
214
223
|
|
215
224
|
:param cluster_identifier: unique identifier of a cluster
|
216
225
|
:param delete_operation: whether the method has been called as part of delete cluster operation
|
@@ -228,7 +237,8 @@ class RedshiftAsyncHook(AwsBaseAsyncHook):
|
|
228
237
|
return {"status": "error", "message": str(error)}
|
229
238
|
|
230
239
|
async def pause_cluster(self, cluster_identifier: str, poll_interval: float = 5.0) -> dict[str, Any]:
|
231
|
-
"""
|
240
|
+
"""
|
241
|
+
Pause the cluster.
|
232
242
|
|
233
243
|
:param cluster_identifier: unique identifier of a cluster
|
234
244
|
:param poll_interval: polling period in seconds to check for the status
|
@@ -255,7 +265,8 @@ class RedshiftAsyncHook(AwsBaseAsyncHook):
|
|
255
265
|
cluster_identifier: str,
|
256
266
|
polling_period_seconds: float = 5.0,
|
257
267
|
) -> dict[str, Any]:
|
258
|
-
"""
|
268
|
+
"""
|
269
|
+
Resume the cluster.
|
259
270
|
|
260
271
|
:param cluster_identifier: unique identifier of a cluster
|
261
272
|
:param polling_period_seconds: polling period in seconds to check for the status
|
@@ -284,7 +295,8 @@ class RedshiftAsyncHook(AwsBaseAsyncHook):
|
|
284
295
|
flag: asyncio.Event,
|
285
296
|
delete_operation: bool = False,
|
286
297
|
) -> dict[str, Any]:
|
287
|
-
"""
|
298
|
+
"""
|
299
|
+
Check for expected Redshift cluster state.
|
288
300
|
|
289
301
|
:param cluster_identifier: unique identifier of a cluster
|
290
302
|
:param expected_state: expected_state example("available", "pausing", "paused"")
|
@@ -231,7 +231,8 @@ class RedshiftDataHook(AwsGenericHook["RedshiftDataAPIServiceClient"]):
|
|
231
231
|
return pk_columns or None
|
232
232
|
|
233
233
|
async def is_still_running(self, statement_id: str) -> bool:
|
234
|
-
"""
|
234
|
+
"""
|
235
|
+
Async function to check whether the query is still running.
|
235
236
|
|
236
237
|
:param statement_id: the UUID of the statement
|
237
238
|
"""
|
@@ -240,7 +241,8 @@ class RedshiftDataHook(AwsGenericHook["RedshiftDataAPIServiceClient"]):
|
|
240
241
|
return desc["Status"] in RUNNING_STATES
|
241
242
|
|
242
243
|
async def check_query_is_finished_async(self, statement_id: str) -> bool:
|
243
|
-
"""
|
244
|
+
"""
|
245
|
+
Async function to check statement is finished.
|
244
246
|
|
245
247
|
It takes statement_id, makes async connection to redshift data to get the query status
|
246
248
|
by statement_id and returns the query status.
|
@@ -39,7 +39,8 @@ if TYPE_CHECKING:
|
|
39
39
|
|
40
40
|
|
41
41
|
class RedshiftSQLHook(DbApiHook):
|
42
|
-
"""
|
42
|
+
"""
|
43
|
+
Execute statements against Amazon Redshift.
|
43
44
|
|
44
45
|
This hook requires the redshift_conn_id connection.
|
45
46
|
|
@@ -103,7 +104,8 @@ class RedshiftSQLHook(DbApiHook):
|
|
103
104
|
return conn_params
|
104
105
|
|
105
106
|
def get_iam_token(self, conn: Connection) -> tuple[str, str, int]:
|
106
|
-
"""
|
107
|
+
"""
|
108
|
+
Retrieve a temporary password to connect to Redshift.
|
107
109
|
|
108
110
|
Port is required. If none is provided, default is used for each service.
|
109
111
|
"""
|
@@ -177,7 +179,8 @@ class RedshiftSQLHook(DbApiHook):
|
|
177
179
|
return create_engine(self.get_uri(), **engine_kwargs)
|
178
180
|
|
179
181
|
def get_table_primary_key(self, table: str, schema: str | None = "public") -> list[str] | None:
|
180
|
-
"""
|
182
|
+
"""
|
183
|
+
Get the table's primary key.
|
181
184
|
|
182
185
|
:param table: Name of the target table
|
183
186
|
:param schema: Name of the target schema, public by default
|