deltafi 2.0rc1720728217472__py3-none-any.whl → 2.0rc1722532930396__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.
- deltafi/action.py +25 -123
- deltafi/actiontype.py +2 -6
- deltafi/domain.py +66 -62
- deltafi/exception.py +0 -10
- deltafi/genericmodel.py +3 -1
- deltafi/input.py +1 -165
- deltafi/logger.py +2 -2
- deltafi/plugin.py +12 -18
- deltafi/result.py +32 -245
- deltafi/test_kit/framework.py +69 -66
- deltafi/test_kit/transform.py +41 -13
- {deltafi-2.0rc1720728217472.dist-info → deltafi-2.0rc1722532930396.dist-info}/METADATA +6 -6
- deltafi-2.0rc1722532930396.dist-info/RECORD +23 -0
- deltafi/test_kit/domain.py +0 -59
- deltafi/test_kit/enrich.py +0 -70
- deltafi/test_kit/format.py +0 -105
- deltafi/test_kit/load.py +0 -128
- deltafi/test_kit/validate.py +0 -54
- deltafi-2.0rc1720728217472.dist-info/RECORD +0 -28
- {deltafi-2.0rc1720728217472.dist-info → deltafi-2.0rc1722532930396.dist-info}/WHEEL +0 -0
deltafi/action.py
CHANGED
|
@@ -20,20 +20,17 @@ from abc import ABC, abstractmethod
|
|
|
20
20
|
from typing import Any, List
|
|
21
21
|
|
|
22
22
|
from deltafi.actiontype import ActionType
|
|
23
|
-
from deltafi.genericmodel import GenericModel
|
|
24
23
|
from deltafi.domain import Context, DeltaFileMessage
|
|
25
|
-
from deltafi.
|
|
24
|
+
from deltafi.genericmodel import GenericModel
|
|
25
|
+
from deltafi.input import EgressInput, TransformInput
|
|
26
26
|
from deltafi.result import *
|
|
27
27
|
from pydantic import BaseModel
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class Action(ABC):
|
|
31
|
-
def __init__(self, action_type: ActionType, description: str,
|
|
32
|
-
requires_enrichments: List[str], valid_result_types: tuple):
|
|
31
|
+
def __init__(self, action_type: ActionType, description: str, valid_result_types: tuple):
|
|
33
32
|
self.action_type = action_type
|
|
34
33
|
self.description = description
|
|
35
|
-
self.requires_domains = requires_domains
|
|
36
|
-
self.requires_enrichments = requires_enrichments
|
|
37
34
|
self.valid_result_types = valid_result_types
|
|
38
35
|
self.action_execution = None
|
|
39
36
|
|
|
@@ -41,8 +38,8 @@ class Action(ABC):
|
|
|
41
38
|
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
42
39
|
pass
|
|
43
40
|
|
|
44
|
-
def
|
|
45
|
-
raise RuntimeError(f"
|
|
41
|
+
def join(self, action_inputs: List[Any]):
|
|
42
|
+
raise RuntimeError(f"Join is not supported for {self.__class__.__name__}")
|
|
46
43
|
|
|
47
44
|
@abstractmethod
|
|
48
45
|
def execute(self, context: Context, action_input: Any, params: BaseModel):
|
|
@@ -51,22 +48,29 @@ class Action(ABC):
|
|
|
51
48
|
def execute_action(self, event):
|
|
52
49
|
if event.delta_file_messages is None or not len(event.delta_file_messages):
|
|
53
50
|
raise RuntimeError(f"Received event with no delta file messages for did {event.context.did}")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
if event.context.join is not None:
|
|
52
|
+
result = self.execute(
|
|
53
|
+
event.context,
|
|
54
|
+
self.join([self.build_input(event.context, delta_file_message)
|
|
55
|
+
for delta_file_message in event.delta_file_messages]),
|
|
56
|
+
self.param_class().model_validate(event.params))
|
|
59
57
|
else:
|
|
60
|
-
result = self.execute(
|
|
61
|
-
|
|
58
|
+
result = self.execute(
|
|
59
|
+
event.context,
|
|
60
|
+
self.build_input(event.context, event.delta_file_messages[0]),
|
|
61
|
+
self.param_class().model_validate(event.params))
|
|
62
62
|
|
|
63
63
|
self.validate_type(result)
|
|
64
64
|
return result
|
|
65
65
|
|
|
66
66
|
@staticmethod
|
|
67
|
-
def param_class(
|
|
67
|
+
def param_class():
|
|
68
68
|
"""Factory method to create and return an empty GenericModel instance.
|
|
69
69
|
|
|
70
|
+
All action parameter classes must inherit pydantic.BaseModel.
|
|
71
|
+
Use of complex types in custom action parameter classes must specify
|
|
72
|
+
the internal types when defined. E.g., dict[str, str], or List[str]
|
|
73
|
+
|
|
70
74
|
Returns
|
|
71
75
|
-------
|
|
72
76
|
GenericModel
|
|
@@ -81,25 +85,9 @@ class Action(ABC):
|
|
|
81
85
|
f"but a {result.__class__.__name__} was returned")
|
|
82
86
|
|
|
83
87
|
|
|
84
|
-
class DomainAction(Action, ABC):
|
|
85
|
-
def __init__(self, description: str, requires_domains: List[str]):
|
|
86
|
-
super().__init__(ActionType.DOMAIN, description, requires_domains, [], (DomainResult, ErrorResult))
|
|
87
|
-
|
|
88
|
-
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
89
|
-
return DomainInput(content=delta_file_message.content_list, metadata=delta_file_message.metadata,
|
|
90
|
-
domains={domain.name: domain for domain in delta_file_message.domains})
|
|
91
|
-
|
|
92
|
-
@abstractmethod
|
|
93
|
-
def domain(self, context: Context, params: BaseModel, domain_input: DomainInput):
|
|
94
|
-
pass
|
|
95
|
-
|
|
96
|
-
def execute(self, context: Context, domain_input: DomainInput, params: BaseModel):
|
|
97
|
-
return self.domain(context, params, domain_input)
|
|
98
|
-
|
|
99
|
-
|
|
100
88
|
class EgressAction(Action, ABC):
|
|
101
89
|
def __init__(self, description: str):
|
|
102
|
-
super().__init__(ActionType.EGRESS, description,
|
|
90
|
+
super().__init__(ActionType.EGRESS, description, (EgressResult, ErrorResult, FilterResult))
|
|
103
91
|
|
|
104
92
|
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
105
93
|
return EgressInput(content=delta_file_message.content_list[0], metadata=delta_file_message.metadata)
|
|
@@ -112,81 +100,9 @@ class EgressAction(Action, ABC):
|
|
|
112
100
|
return self.egress(context, params, egress_input)
|
|
113
101
|
|
|
114
102
|
|
|
115
|
-
class EnrichAction(Action, ABC):
|
|
116
|
-
def __init__(self, description: str, requires_domains: List[str], requires_enrichments: List[str]):
|
|
117
|
-
super().__init__(ActionType.ENRICH, description, requires_domains, requires_enrichments,
|
|
118
|
-
(EnrichResult, ErrorResult))
|
|
119
|
-
|
|
120
|
-
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
121
|
-
return EnrichInput(content=delta_file_message.content_list, metadata=delta_file_message.metadata,
|
|
122
|
-
domains={domain.name: domain for domain in delta_file_message.domains},
|
|
123
|
-
enrichments={domain.name: domain for domain in delta_file_message.enrichments})
|
|
124
|
-
|
|
125
|
-
@abstractmethod
|
|
126
|
-
def enrich(self, context: Context, params: BaseModel, enrich_input: EnrichInput):
|
|
127
|
-
pass
|
|
128
|
-
|
|
129
|
-
def execute(self, context: Context, enrich_input: EnrichInput, params: BaseModel):
|
|
130
|
-
return self.enrich(context, params, enrich_input)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
class FormatAction(Action, ABC):
|
|
134
|
-
def __init__(self, description: str, requires_domains: List[str], requires_enrichments: List[str]):
|
|
135
|
-
super().__init__(ActionType.FORMAT, description, requires_domains, requires_enrichments,
|
|
136
|
-
(FormatResult, FormatManyResult, ErrorResult, FilterResult))
|
|
137
|
-
|
|
138
|
-
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
139
|
-
return FormatInput(content=delta_file_message.content_list, metadata=delta_file_message.metadata,
|
|
140
|
-
domains={domain.name: domain for domain in delta_file_message.domains},
|
|
141
|
-
enrichments={domain.name: domain for domain in delta_file_message.enrichments})
|
|
142
|
-
|
|
143
|
-
def collect(self, format_inputs: List[FormatInput]):
|
|
144
|
-
all_content = []
|
|
145
|
-
all_metadata = {}
|
|
146
|
-
all_domains = {}
|
|
147
|
-
all_enrichments = {}
|
|
148
|
-
for format_input in format_inputs:
|
|
149
|
-
all_content += format_input.content
|
|
150
|
-
all_metadata.update(format_input.metadata)
|
|
151
|
-
all_domains.update(format_input.domains)
|
|
152
|
-
all_enrichments.update(format_input.enrichments)
|
|
153
|
-
return FormatInput(content=all_content, metadata=all_metadata, domains=all_domains, enrichments=all_enrichments)
|
|
154
|
-
|
|
155
|
-
@abstractmethod
|
|
156
|
-
def format(self, context: Context, params: BaseModel, format_input: FormatInput):
|
|
157
|
-
pass
|
|
158
|
-
|
|
159
|
-
def execute(self, context: Context, format_input: FormatInput, params: BaseModel):
|
|
160
|
-
return self.format(context, params, format_input)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
class LoadAction(Action, ABC):
|
|
164
|
-
def __init__(self, description: str):
|
|
165
|
-
super().__init__(ActionType.LOAD, description, [], [],
|
|
166
|
-
(LoadResult, LoadManyResult, ErrorResult, FilterResult, ReinjectResult))
|
|
167
|
-
|
|
168
|
-
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
169
|
-
return LoadInput(content=delta_file_message.content_list, metadata=delta_file_message.metadata)
|
|
170
|
-
|
|
171
|
-
def collect(self, load_inputs: List[LoadInput]):
|
|
172
|
-
all_content = []
|
|
173
|
-
all_metadata = {}
|
|
174
|
-
for load_input in load_inputs:
|
|
175
|
-
all_content += load_input.content
|
|
176
|
-
all_metadata.update(load_input.metadata)
|
|
177
|
-
return LoadInput(content=all_content, metadata=all_metadata)
|
|
178
|
-
|
|
179
|
-
@abstractmethod
|
|
180
|
-
def load(self, context: Context, params: BaseModel, load_input: LoadInput):
|
|
181
|
-
pass
|
|
182
|
-
|
|
183
|
-
def execute(self, context: Context, load_input: LoadInput, params: BaseModel):
|
|
184
|
-
return self.load(context, params, load_input)
|
|
185
|
-
|
|
186
|
-
|
|
187
103
|
class TimedIngressAction(Action, ABC):
|
|
188
104
|
def __init__(self, description: str):
|
|
189
|
-
super().__init__(ActionType.TIMED_INGRESS, description,
|
|
105
|
+
super().__init__(ActionType.TIMED_INGRESS, description, (IngressResult, ErrorResult))
|
|
190
106
|
|
|
191
107
|
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
192
108
|
return None
|
|
@@ -201,12 +117,13 @@ class TimedIngressAction(Action, ABC):
|
|
|
201
117
|
|
|
202
118
|
class TransformAction(Action, ABC):
|
|
203
119
|
def __init__(self, description: str):
|
|
204
|
-
super().__init__(ActionType.TRANSFORM, description,
|
|
120
|
+
super().__init__(ActionType.TRANSFORM, description,
|
|
121
|
+
(TransformResult, TransformResults, ErrorResult, FilterResult))
|
|
205
122
|
|
|
206
123
|
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
207
124
|
return TransformInput(content=delta_file_message.content_list, metadata=delta_file_message.metadata)
|
|
208
125
|
|
|
209
|
-
def
|
|
126
|
+
def join(self, transform_inputs: List[TransformInput]):
|
|
210
127
|
all_content = []
|
|
211
128
|
all_metadata = {}
|
|
212
129
|
for transform_input in transform_inputs:
|
|
@@ -220,18 +137,3 @@ class TransformAction(Action, ABC):
|
|
|
220
137
|
|
|
221
138
|
def execute(self, context: Context, transform_input: TransformInput, params: BaseModel):
|
|
222
139
|
return self.transform(context, params, transform_input)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
class ValidateAction(Action, ABC):
|
|
226
|
-
def __init__(self, description: str):
|
|
227
|
-
super().__init__(ActionType.VALIDATE, description, [], [], (ValidateResult, ErrorResult, FilterResult))
|
|
228
|
-
|
|
229
|
-
def build_input(self, context: Context, delta_file_message: DeltaFileMessage):
|
|
230
|
-
return ValidateInput(content=delta_file_message.content_list[0], metadata=delta_file_message.metadata)
|
|
231
|
-
|
|
232
|
-
@abstractmethod
|
|
233
|
-
def validate(self, context: Context, params: BaseModel, validate_input: ValidateInput):
|
|
234
|
-
pass
|
|
235
|
-
|
|
236
|
-
def execute(self, context: Context, validate_input: ValidateInput, params: BaseModel):
|
|
237
|
-
return self.validate(context, params, validate_input)
|
deltafi/actiontype.py
CHANGED
|
@@ -20,13 +20,9 @@ from enum import Enum
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class ActionType(Enum):
|
|
23
|
+
INGRESS = "INGRESS"
|
|
23
24
|
TIMED_INGRESS = "TIMED_INGRESS"
|
|
24
25
|
TRANSFORM = "TRANSFORM"
|
|
25
|
-
LOAD = "LOAD"
|
|
26
|
-
DOMAIN = "DOMAIN"
|
|
27
|
-
ENRICH = "ENRICH"
|
|
28
|
-
FORMAT = "FORMAT"
|
|
29
|
-
VALIDATE = "VALIDATE"
|
|
30
26
|
EGRESS = "EGRESS"
|
|
31
|
-
|
|
27
|
+
PUBLISH = "PUBLISH"
|
|
32
28
|
UNKNOWN = "UNKNOWN"
|
deltafi/domain.py
CHANGED
|
@@ -40,59 +40,87 @@ class ActionExecution(NamedTuple):
|
|
|
40
40
|
|
|
41
41
|
class Context(NamedTuple):
|
|
42
42
|
did: str
|
|
43
|
-
|
|
43
|
+
delta_file_name: str
|
|
44
|
+
data_source: str
|
|
45
|
+
flow_name: str
|
|
46
|
+
flow_id: str
|
|
44
47
|
action_name: str
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
egress_flow: str
|
|
48
|
-
system: str
|
|
48
|
+
action_id: str
|
|
49
|
+
action_version: str
|
|
49
50
|
hostname: str
|
|
51
|
+
system_name: str
|
|
50
52
|
content_service: ContentService
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
join: dict = None
|
|
54
|
+
joined_dids: List[str] = None
|
|
53
55
|
memo: str = None
|
|
54
56
|
logger: Logger = None
|
|
55
57
|
|
|
56
58
|
@classmethod
|
|
57
|
-
def create(cls, context: dict,
|
|
59
|
+
def create(cls, context: dict, content_service: ContentService, logger: Logger):
|
|
58
60
|
did = context['did']
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
action_name = action_name_parts[1]
|
|
62
|
-
if 'sourceFilename' in context:
|
|
63
|
-
source_filename = context['sourceFilename']
|
|
61
|
+
if 'deltaFileName' in context:
|
|
62
|
+
delta_file_name = context['deltaFileName']
|
|
64
63
|
else:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
egress_flow = context['egressFlow']
|
|
64
|
+
delta_file_name = None
|
|
65
|
+
if 'dataSource' in context:
|
|
66
|
+
data_source = context['dataSource']
|
|
69
67
|
else:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
collect = context['collect']
|
|
68
|
+
data_source = None
|
|
69
|
+
if 'flowName' in context:
|
|
70
|
+
flow_name = context['flowName']
|
|
74
71
|
else:
|
|
75
|
-
|
|
76
|
-
if '
|
|
77
|
-
|
|
72
|
+
flow_name = None
|
|
73
|
+
if 'flowId' in context:
|
|
74
|
+
flow_id = context['flowId']
|
|
78
75
|
else:
|
|
79
|
-
|
|
76
|
+
flow_id = None
|
|
77
|
+
if 'actionName' in context:
|
|
78
|
+
action_name = context['actionName']
|
|
79
|
+
else:
|
|
80
|
+
action_name = None
|
|
81
|
+
if 'actionId' in context:
|
|
82
|
+
action_id = context['actionId']
|
|
83
|
+
else:
|
|
84
|
+
action_id = None
|
|
85
|
+
if 'actionVersion' in context:
|
|
86
|
+
action_version = context['actionVersion']
|
|
87
|
+
else:
|
|
88
|
+
action_version = None
|
|
89
|
+
if 'hostname' in context:
|
|
90
|
+
hostname = context['hostname']
|
|
91
|
+
else:
|
|
92
|
+
hostname = None
|
|
93
|
+
if 'systemName' in context:
|
|
94
|
+
system_name = context['systemName']
|
|
95
|
+
else:
|
|
96
|
+
system_name = None
|
|
97
|
+
if 'join' in context:
|
|
98
|
+
join = context['join']
|
|
99
|
+
else:
|
|
100
|
+
join = None
|
|
101
|
+
if 'joinedDids' in context:
|
|
102
|
+
joined_dids = context['joinedDids']
|
|
103
|
+
else:
|
|
104
|
+
joined_dids = None
|
|
80
105
|
if 'memo' in context:
|
|
81
106
|
memo = context['memo']
|
|
82
107
|
else:
|
|
83
108
|
memo = None
|
|
109
|
+
|
|
84
110
|
return Context(did=did,
|
|
85
|
-
|
|
111
|
+
delta_file_name=delta_file_name,
|
|
112
|
+
data_source=data_source,
|
|
113
|
+
flow_name=flow_name,
|
|
114
|
+
flow_id=flow_id,
|
|
86
115
|
action_name=action_name,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
egress_flow=egress_flow,
|
|
90
|
-
system=system,
|
|
116
|
+
action_id=action_id,
|
|
117
|
+
action_version=action_version,
|
|
91
118
|
hostname=hostname,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
119
|
+
system_name=system_name,
|
|
120
|
+
join=join,
|
|
121
|
+
joined_dids=joined_dids,
|
|
95
122
|
memo=memo,
|
|
123
|
+
content_service=content_service,
|
|
96
124
|
logger=logger)
|
|
97
125
|
|
|
98
126
|
|
|
@@ -197,7 +225,6 @@ class Content:
|
|
|
197
225
|
|
|
198
226
|
return new_segments
|
|
199
227
|
|
|
200
|
-
|
|
201
228
|
def get_size(self):
|
|
202
229
|
"""
|
|
203
230
|
Returns the size of the content in bytes.
|
|
@@ -296,41 +323,17 @@ class Content:
|
|
|
296
323
|
content_service=content_service)
|
|
297
324
|
|
|
298
325
|
|
|
299
|
-
class Domain(NamedTuple):
|
|
300
|
-
name: str
|
|
301
|
-
value: str
|
|
302
|
-
media_type: str
|
|
303
|
-
|
|
304
|
-
@classmethod
|
|
305
|
-
def from_dict(cls, domain: dict):
|
|
306
|
-
name = domain['name']
|
|
307
|
-
if 'value' in domain:
|
|
308
|
-
value = domain['value']
|
|
309
|
-
else:
|
|
310
|
-
value = None
|
|
311
|
-
media_type = domain['mediaType']
|
|
312
|
-
return Domain(name=name,
|
|
313
|
-
value=value,
|
|
314
|
-
media_type=media_type)
|
|
315
|
-
|
|
316
|
-
|
|
317
326
|
class DeltaFileMessage(NamedTuple):
|
|
318
327
|
metadata: Dict[str, str]
|
|
319
328
|
content_list: List[Content]
|
|
320
|
-
domains: List[Domain]
|
|
321
|
-
enrichments: List[Domain]
|
|
322
329
|
|
|
323
330
|
@classmethod
|
|
324
331
|
def from_dict(cls, delta_file_message: dict, content_service: ContentService):
|
|
325
332
|
metadata = delta_file_message['metadata']
|
|
326
333
|
content_list = [Content.from_dict(content, content_service) for content in delta_file_message['contentList']]
|
|
327
|
-
domains = [Domain.from_dict(domain) for domain in delta_file_message['domains']] if 'domains' in delta_file_message else []
|
|
328
|
-
enrichments = [Domain.from_dict(domain) for domain in delta_file_message['enrichments']] if 'enrichments' in delta_file_message else []
|
|
329
334
|
|
|
330
335
|
return DeltaFileMessage(metadata=metadata,
|
|
331
|
-
content_list=content_list
|
|
332
|
-
domains=domains,
|
|
333
|
-
enrichments=enrichments)
|
|
336
|
+
content_list=content_list)
|
|
334
337
|
|
|
335
338
|
|
|
336
339
|
class Event(NamedTuple):
|
|
@@ -341,9 +344,10 @@ class Event(NamedTuple):
|
|
|
341
344
|
return_address: str
|
|
342
345
|
|
|
343
346
|
@classmethod
|
|
344
|
-
def create(cls, event: dict,
|
|
345
|
-
delta_file_messages = [DeltaFileMessage.from_dict(delta_file_message, content_service) for delta_file_message in
|
|
346
|
-
|
|
347
|
+
def create(cls, event: dict, content_service: ContentService, logger: Logger):
|
|
348
|
+
delta_file_messages = [DeltaFileMessage.from_dict(delta_file_message, content_service) for delta_file_message in
|
|
349
|
+
event['deltaFileMessages']]
|
|
350
|
+
context = Context.create(event['actionContext'], content_service, logger)
|
|
347
351
|
params = event['actionParams']
|
|
348
352
|
queue_name = None
|
|
349
353
|
if 'queueName' in event:
|
deltafi/exception.py
CHANGED
|
@@ -23,16 +23,6 @@ class ExpectedContentException(RuntimeError):
|
|
|
23
23
|
self.size = size
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class MissingDomainException(RuntimeError):
|
|
27
|
-
def __init__(self, name):
|
|
28
|
-
self.name = name
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class MissingEnrichmentException(RuntimeError):
|
|
32
|
-
def __init__(self, name):
|
|
33
|
-
self.name = name
|
|
34
|
-
|
|
35
|
-
|
|
36
26
|
class MissingMetadataException(RuntimeError):
|
|
37
27
|
def __init__(self, key):
|
|
38
28
|
self.key = key
|
deltafi/genericmodel.py
CHANGED
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
|
|
23
23
|
Provides an empty subclass of pydantic.BaseModel.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
All action parameter classes must inherit pydantic.BaseModel.
|
|
26
|
+
|
|
27
|
+
Starting Pydantic v2, the BaseModel cannot be directly instantiated. This class provides for instantiation of GenericModel objects that inherit from BaseModel.
|
|
26
28
|
|
|
27
29
|
This class does not define fields for validation or any other purpose.
|
|
28
30
|
"""
|
deltafi/input.py
CHANGED
|
@@ -17,172 +17,13 @@
|
|
|
17
17
|
#
|
|
18
18
|
|
|
19
19
|
from deltafi.domain import *
|
|
20
|
-
from deltafi.exception import MissingMetadataException, ExpectedContentException
|
|
21
|
-
MissingEnrichmentException
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class DomainInput(NamedTuple):
|
|
25
|
-
content: List[Content]
|
|
26
|
-
metadata: Dict[str, str]
|
|
27
|
-
domains: Dict[str, Domain]
|
|
28
|
-
|
|
29
|
-
def has_content(self) -> bool:
|
|
30
|
-
return len(self.content) > 0
|
|
31
|
-
|
|
32
|
-
def content_at(self, index: int) -> Content:
|
|
33
|
-
if len(self.content) < index + 1:
|
|
34
|
-
raise ExpectedContentException(index, len(self.content))
|
|
35
|
-
return self.content[index]
|
|
36
|
-
|
|
37
|
-
def first_content(self):
|
|
38
|
-
return self.content_at(0)
|
|
39
|
-
|
|
40
|
-
def get_metadata(self, key: str):
|
|
41
|
-
if key in self.metadata:
|
|
42
|
-
return self.metadata[key]
|
|
43
|
-
else:
|
|
44
|
-
raise MissingMetadataException(key)
|
|
45
|
-
|
|
46
|
-
def get_metadata_or_else(self, key: str, default: str) -> str:
|
|
47
|
-
if key in self.metadata:
|
|
48
|
-
return self.metadata[key]
|
|
49
|
-
else:
|
|
50
|
-
return default
|
|
51
|
-
|
|
52
|
-
def has_domain(self, name: str) -> bool:
|
|
53
|
-
return name in self.domains
|
|
54
|
-
|
|
55
|
-
def domain(self, name: str) -> Domain:
|
|
56
|
-
if not self.has_domain(name):
|
|
57
|
-
raise MissingDomainException(name)
|
|
58
|
-
return self.domains[name]
|
|
59
|
-
|
|
20
|
+
from deltafi.exception import MissingMetadataException, ExpectedContentException
|
|
60
21
|
|
|
61
22
|
class EgressInput(NamedTuple):
|
|
62
23
|
content: Content
|
|
63
24
|
metadata: dict
|
|
64
25
|
|
|
65
26
|
|
|
66
|
-
class EnrichInput(NamedTuple):
|
|
67
|
-
content: List[Content]
|
|
68
|
-
metadata: dict
|
|
69
|
-
domains: Dict[str, Domain]
|
|
70
|
-
enrichments: Dict[str, Domain]
|
|
71
|
-
|
|
72
|
-
def has_content(self) -> bool:
|
|
73
|
-
return len(self.content) > 0
|
|
74
|
-
|
|
75
|
-
def content_at(self, index: int) -> Content:
|
|
76
|
-
if len(self.content) < index + 1:
|
|
77
|
-
raise ExpectedContentException(index, len(self.content))
|
|
78
|
-
return self.content[index]
|
|
79
|
-
|
|
80
|
-
def first_content(self):
|
|
81
|
-
return self.content_at(0)
|
|
82
|
-
|
|
83
|
-
def get_metadata(self, key: str):
|
|
84
|
-
if key in self.metadata:
|
|
85
|
-
return self.metadata[key]
|
|
86
|
-
else:
|
|
87
|
-
raise MissingMetadataException(key)
|
|
88
|
-
|
|
89
|
-
def get_metadata_or_else(self, key: str, default: str) -> str:
|
|
90
|
-
if key in self.metadata:
|
|
91
|
-
return self.metadata[key]
|
|
92
|
-
else:
|
|
93
|
-
return default
|
|
94
|
-
|
|
95
|
-
def has_domain(self, name: str) -> bool:
|
|
96
|
-
return name in self.domains
|
|
97
|
-
|
|
98
|
-
def domain(self, name: str) -> Domain:
|
|
99
|
-
if not self.has_domain(name):
|
|
100
|
-
raise MissingDomainException(name)
|
|
101
|
-
return self.domains[name]
|
|
102
|
-
|
|
103
|
-
def has_enrichment(self, name: str) -> bool:
|
|
104
|
-
return name in self.enrichments
|
|
105
|
-
|
|
106
|
-
def enrichment(self, name: str) -> Domain:
|
|
107
|
-
if not self.has_enrichment(name):
|
|
108
|
-
raise MissingEnrichmentException(name)
|
|
109
|
-
return self.enrichments[name]
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
class FormatInput(NamedTuple):
|
|
113
|
-
content: List[Content]
|
|
114
|
-
metadata: dict
|
|
115
|
-
domains: Dict[str, Domain]
|
|
116
|
-
enrichments: Dict[str, Domain]
|
|
117
|
-
|
|
118
|
-
def has_content(self) -> bool:
|
|
119
|
-
return len(self.content) > 0
|
|
120
|
-
|
|
121
|
-
def content_at(self, index: int) -> Content:
|
|
122
|
-
if len(self.content) < index + 1:
|
|
123
|
-
raise ExpectedContentException(index, len(self.content))
|
|
124
|
-
return self.content[index]
|
|
125
|
-
|
|
126
|
-
def first_content(self):
|
|
127
|
-
return self.content_at(0)
|
|
128
|
-
|
|
129
|
-
def get_metadata(self, key: str):
|
|
130
|
-
if key in self.metadata:
|
|
131
|
-
return self.metadata[key]
|
|
132
|
-
else:
|
|
133
|
-
raise MissingMetadataException(key)
|
|
134
|
-
|
|
135
|
-
def get_metadata_or_else(self, key: str, default: str) -> str:
|
|
136
|
-
if key in self.metadata:
|
|
137
|
-
return self.metadata[key]
|
|
138
|
-
else:
|
|
139
|
-
return default
|
|
140
|
-
|
|
141
|
-
def has_domain(self, name: str) -> bool:
|
|
142
|
-
return name in self.domains
|
|
143
|
-
|
|
144
|
-
def domain(self, name: str) -> Domain:
|
|
145
|
-
if not self.has_domain(name):
|
|
146
|
-
raise MissingDomainException(name)
|
|
147
|
-
return self.domains[name]
|
|
148
|
-
|
|
149
|
-
def has_enrichment(self, name: str) -> bool:
|
|
150
|
-
return name in self.enrichments
|
|
151
|
-
|
|
152
|
-
def enrichment(self, name: str) -> Domain:
|
|
153
|
-
if not self.has_enrichment(name):
|
|
154
|
-
raise MissingEnrichmentException(name)
|
|
155
|
-
return self.enrichments[name]
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
class LoadInput(NamedTuple):
|
|
159
|
-
content: List[Content]
|
|
160
|
-
metadata: dict
|
|
161
|
-
|
|
162
|
-
def has_content(self) -> bool:
|
|
163
|
-
return len(self.content) > 0
|
|
164
|
-
|
|
165
|
-
def content_at(self, index: int) -> Content:
|
|
166
|
-
if len(self.content) < index + 1:
|
|
167
|
-
raise ExpectedContentException(index, len(self.content))
|
|
168
|
-
return self.content[index]
|
|
169
|
-
|
|
170
|
-
def first_content(self):
|
|
171
|
-
return self.content_at(0)
|
|
172
|
-
|
|
173
|
-
def get_metadata(self, key: str):
|
|
174
|
-
if key in self.metadata:
|
|
175
|
-
return self.metadata[key]
|
|
176
|
-
else:
|
|
177
|
-
raise MissingMetadataException(key)
|
|
178
|
-
|
|
179
|
-
def get_metadata_or_else(self, key: str, default: str) -> str:
|
|
180
|
-
if key in self.metadata:
|
|
181
|
-
return self.metadata[key]
|
|
182
|
-
else:
|
|
183
|
-
return default
|
|
184
|
-
|
|
185
|
-
|
|
186
27
|
class TransformInput(NamedTuple):
|
|
187
28
|
content: List[Content]
|
|
188
29
|
metadata: dict
|
|
@@ -209,8 +50,3 @@ class TransformInput(NamedTuple):
|
|
|
209
50
|
return self.metadata[key]
|
|
210
51
|
else:
|
|
211
52
|
return default
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
class ValidateInput(NamedTuple):
|
|
215
|
-
content: Content
|
|
216
|
-
metadata: dict
|
deltafi/logger.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import logging
|
|
20
20
|
import sys
|
|
21
|
-
from datetime import datetime
|
|
21
|
+
from datetime import datetime, UTC
|
|
22
22
|
|
|
23
23
|
import json_logging
|
|
24
24
|
|
|
@@ -42,7 +42,7 @@ def _sanitize_log_msg(record):
|
|
|
42
42
|
class JSONLogFormatter(json_logging.JSONLogFormatter):
|
|
43
43
|
|
|
44
44
|
def _format_log_object(self, record, request_util):
|
|
45
|
-
utcnow = datetime.
|
|
45
|
+
utcnow = datetime.now(UTC)
|
|
46
46
|
|
|
47
47
|
json_log_object = {
|
|
48
48
|
'timestamp': json_logging.util.iso_time_format(utcnow),
|