airless-google-cloud-core 0.0.4__tar.gz → 0.1.0.dev0__tar.gz
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.
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/PKG-INFO +3 -3
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/core/operator/__init__.py +0 -2
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless_google_cloud_core.egg-info/PKG-INFO +3 -3
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless_google_cloud_core.egg-info/SOURCES.txt +0 -1
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless_google_cloud_core.egg-info/requires.txt +1 -1
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/pyproject.toml +1 -1
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/requirements.txt +1 -1
- airless_google_cloud_core-0.0.4/airless/google/cloud/core/operator/error.py +0 -137
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/README.md +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/core/__init__.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/core/operator/base.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/core/operator/delay.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/core/operator/redirect.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/pubsub/__init__.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/pubsub/hook/__init__.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless/google/cloud/pubsub/hook/pubsub.py +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless_google_cloud_core.egg-info/dependency_links.txt +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/airless_google_cloud_core.egg-info/top_level.txt +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/setup.cfg +0 -0
- {airless_google_cloud_core-0.0.4 → airless_google_cloud_core-0.1.0.dev0}/tests/test_fake.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: airless-google-cloud-core
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
4
|
Summary: Airless package with the main components to use airless in google cloud
|
|
5
5
|
License: MIT License
|
|
6
6
|
Project-URL: Homepage, https://github.com/astercapital/airless
|
|
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/astercapital/airless/issues
|
|
|
8
8
|
Requires-Python: >=3.9
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: google-cloud-pubsub<3.0.0,>=2.13.11
|
|
11
|
-
Requires-Dist: airless-core<0.
|
|
11
|
+
Requires-Dist: airless-core<0.3.0,>=0.2.1.dev1
|
|
12
12
|
|
|
13
13
|
# airless-google-cloud-core
|
|
14
14
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
from .base import (GoogleBaseEventOperator, GoogleBaseFileOperator)
|
|
2
2
|
from .delay import (GoogleDelayOperator)
|
|
3
|
-
from .error import (GoogleErrorReprocessOperator)
|
|
4
3
|
from .redirect import (GoogleRedirectOperator)
|
|
5
4
|
|
|
6
5
|
__all__ = [
|
|
7
6
|
'GoogleBaseEventOperator',
|
|
8
7
|
'GoogleBaseFileOperator',
|
|
9
8
|
'GoogleDelayOperator',
|
|
10
|
-
'GoogleErrorReprocessOperator',
|
|
11
9
|
'GoogleRedirectOperator'
|
|
12
10
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: airless-google-cloud-core
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
4
|
Summary: Airless package with the main components to use airless in google cloud
|
|
5
5
|
License: MIT License
|
|
6
6
|
Project-URL: Homepage, https://github.com/astercapital/airless
|
|
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/astercapital/airless/issues
|
|
|
8
8
|
Requires-Python: >=3.9
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: google-cloud-pubsub<3.0.0,>=2.13.11
|
|
11
|
-
Requires-Dist: airless-core<0.
|
|
11
|
+
Requires-Dist: airless-core<0.3.0,>=0.2.1.dev1
|
|
12
12
|
|
|
13
13
|
# airless-google-cloud-core
|
|
14
14
|
|
|
@@ -5,7 +5,6 @@ airless/google/cloud/core/__init__.py
|
|
|
5
5
|
airless/google/cloud/core/operator/__init__.py
|
|
6
6
|
airless/google/cloud/core/operator/base.py
|
|
7
7
|
airless/google/cloud/core/operator/delay.py
|
|
8
|
-
airless/google/cloud/core/operator/error.py
|
|
9
8
|
airless/google/cloud/core/operator/redirect.py
|
|
10
9
|
airless/google/cloud/pubsub/__init__.py
|
|
11
10
|
airless/google/cloud/pubsub/hook/__init__.py
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
google-cloud-pubsub<3.0.0,>=2.13.11
|
|
2
|
-
airless-core<0.
|
|
2
|
+
airless-core<0.3.0,>=0.2.1.dev1
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import json
|
|
3
|
-
import time
|
|
4
|
-
from typing import Any, Dict, List, Optional
|
|
5
|
-
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
|
|
8
|
-
from airless.core.utils import get_config
|
|
9
|
-
from airless.core.dto import BaseDto
|
|
10
|
-
from airless.google.cloud.core.operator import GoogleBaseEventOperator
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class GoogleErrorReprocessOperator(GoogleBaseEventOperator):
|
|
14
|
-
"""Operator for reprocessing errors in Google Cloud."""
|
|
15
|
-
|
|
16
|
-
def __init__(self) -> None:
|
|
17
|
-
"""Initializes the GoogleErrorReprocessOperator."""
|
|
18
|
-
super().__init__()
|
|
19
|
-
|
|
20
|
-
def execute(self, data: Dict[str, Any], topic: str) -> None:
|
|
21
|
-
"""Executes the error reprocessing logic.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
data (Dict[str, Any]): The input data containing error information.
|
|
25
|
-
topic (str): The Pub/Sub topic to publish messages to.
|
|
26
|
-
"""
|
|
27
|
-
input_type = data['input_type']
|
|
28
|
-
origin = data.get('origin', 'undefined')
|
|
29
|
-
message_id = data.get('event_id')
|
|
30
|
-
original_data = data['data']
|
|
31
|
-
metadata = original_data.get('metadata', {})
|
|
32
|
-
|
|
33
|
-
retry_interval = metadata.get('retry_interval', 5)
|
|
34
|
-
retries = metadata.get('retries', 0)
|
|
35
|
-
max_retries = metadata.get('max_retries', 2)
|
|
36
|
-
max_interval = metadata.get('max_interval', 480)
|
|
37
|
-
|
|
38
|
-
if (input_type == 'event') and (retries < max_retries):
|
|
39
|
-
time.sleep(min(retry_interval ** retries, max_interval))
|
|
40
|
-
original_data.setdefault('metadata', {})['retries'] = retries + 1
|
|
41
|
-
self.queue_hook.publish(
|
|
42
|
-
project=get_config('GCP_PROJECT'),
|
|
43
|
-
topic=origin,
|
|
44
|
-
data=original_data)
|
|
45
|
-
|
|
46
|
-
else:
|
|
47
|
-
dto = BaseDto(
|
|
48
|
-
event_id=message_id,
|
|
49
|
-
resource=origin,
|
|
50
|
-
to_project=get_config('GCP_PROJECT'),
|
|
51
|
-
to_dataset=get_config('BIGQUERY_DATASET_ERROR'),
|
|
52
|
-
to_table=get_config('BIGQUERY_TABLE_ERROR'),
|
|
53
|
-
to_schema=None,
|
|
54
|
-
to_partition_column='_created_at',
|
|
55
|
-
to_extract_to_cols=False,
|
|
56
|
-
to_keys_format=None,
|
|
57
|
-
data=data)
|
|
58
|
-
self.queue_hook.publish(
|
|
59
|
-
project=get_config('GCP_PROJECT'),
|
|
60
|
-
topic=get_config('PUBSUB_TOPIC_PUBSUB_TO_BQ'),
|
|
61
|
-
data=dto.as_dict())
|
|
62
|
-
|
|
63
|
-
email_send_topic = get_config('PUBSUB_TOPIC_EMAIL_SEND', False)
|
|
64
|
-
if email_send_topic and (origin != email_send_topic):
|
|
65
|
-
self.notify_email(origin, message_id, data)
|
|
66
|
-
|
|
67
|
-
slack_send_topic = get_config('PUBSUB_TOPIC_SLACK_SEND', False)
|
|
68
|
-
if slack_send_topic and (origin != slack_send_topic):
|
|
69
|
-
self.notify_slack(origin, message_id, data)
|
|
70
|
-
|
|
71
|
-
def notify_email(self, origin: str, message_id: str, data: Dict[str, Any]) -> None:
|
|
72
|
-
"""Sends a notification email.
|
|
73
|
-
|
|
74
|
-
Args:
|
|
75
|
-
origin (str): The origin of the error.
|
|
76
|
-
message_id (str): The ID of the message.
|
|
77
|
-
data (Dict[str, Any]): The data related to the error.
|
|
78
|
-
"""
|
|
79
|
-
email_message = {
|
|
80
|
-
'sender': get_config('EMAIL_SENDER_ERROR'),
|
|
81
|
-
'recipients': eval(get_config('EMAIL_RECIPIENTS_ERROR')),
|
|
82
|
-
'subject': f'{origin} | {message_id}',
|
|
83
|
-
'content': f'Input Type: {data["input_type"]} Origin: {origin}\nMessage ID: {message_id}\n\n {json.dumps(data["data"])}\n\n{data["error"]}'
|
|
84
|
-
}
|
|
85
|
-
self.queue_hook.publish(
|
|
86
|
-
project=get_config('GCP_PROJECT'),
|
|
87
|
-
topic=get_config('PUBSUB_TOPIC_EMAIL_SEND'),
|
|
88
|
-
data=email_message)
|
|
89
|
-
|
|
90
|
-
def notify_slack(self, origin: str, message_id: str, data: Dict[str, Any]) -> None:
|
|
91
|
-
"""Sends a notification to Slack.
|
|
92
|
-
|
|
93
|
-
Args:
|
|
94
|
-
origin (str): The origin of the error.
|
|
95
|
-
message_id (str): The ID of the message.
|
|
96
|
-
data (Dict[str, Any]): The data related to the error.
|
|
97
|
-
"""
|
|
98
|
-
slack_message = {
|
|
99
|
-
'channels': eval(get_config('SLACK_CHANNELS_ERROR')),
|
|
100
|
-
'message': f'{origin} | {message_id}\n\n{json.dumps(data["data"])}\n\n{data["error"]}'
|
|
101
|
-
}
|
|
102
|
-
self.queue_hook.publish(
|
|
103
|
-
project=get_config('GCP_PROJECT'),
|
|
104
|
-
topic=get_config('PUBSUB_TOPIC_SLACK_SEND'),
|
|
105
|
-
data=slack_message)
|
|
106
|
-
|
|
107
|
-
def prepare_row(self, row: Dict[str, Any], message_id: Optional[str], origin: Optional[str]) -> Dict[str, Any]:
|
|
108
|
-
"""Prepares a row for insertion.
|
|
109
|
-
|
|
110
|
-
Args:
|
|
111
|
-
row (Dict[str, Any]): The row data.
|
|
112
|
-
message_id (Optional[str]): The message ID.
|
|
113
|
-
origin (Optional[str]): The origin of the message.
|
|
114
|
-
|
|
115
|
-
Returns:
|
|
116
|
-
Dict[str, Any]: The prepared row.
|
|
117
|
-
"""
|
|
118
|
-
return {
|
|
119
|
-
'_event_id': message_id or 1234,
|
|
120
|
-
'_resource': origin or 'local',
|
|
121
|
-
'_json': json.dumps(row),
|
|
122
|
-
'_created_at': str(datetime.now())
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
def prepare_rows(self, data: Any, message_id: Optional[str], origin: Optional[str]) -> List[Dict[str, Any]]:
|
|
126
|
-
"""Prepares multiple rows for insertion.
|
|
127
|
-
|
|
128
|
-
Args:
|
|
129
|
-
data (Any): The data to prepare.
|
|
130
|
-
message_id (Optional[str]): The message ID.
|
|
131
|
-
origin (Optional[str]): The origin of the message.
|
|
132
|
-
|
|
133
|
-
Returns:
|
|
134
|
-
List[Dict[str, Any]]: The list of prepared rows.
|
|
135
|
-
"""
|
|
136
|
-
prepared_rows = data if isinstance(data, list) else [data]
|
|
137
|
-
return [self.prepare_row(row, message_id, origin) for row in prepared_rows]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|