maleo-schemas 0.0.1__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.
- maleo/schemas/__init__.py +0 -0
- maleo/schemas/operation/__init__.py +0 -0
- maleo/schemas/operation/action.py +9 -0
- maleo/schemas/operation/base.py +230 -0
- maleo/schemas/operation/request.py +128 -0
- maleo/schemas/operation/resource.py +853 -0
- maleo/schemas/operation/system.py +65 -0
- maleo/schemas/request.py +44 -0
- maleo/schemas/response.py +373 -0
- maleo_schemas-0.0.1.dist-info/METADATA +111 -0
- maleo_schemas-0.0.1.dist-info/RECORD +14 -0
- maleo_schemas-0.0.1.dist-info/WHEEL +5 -0
- maleo_schemas-0.0.1.dist-info/licenses/LICENSE +57 -0
- maleo_schemas-0.0.1.dist-info/top_level.txt +1 -0
File without changes
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
from typing import Generic, Optional, TypeVar
|
3
|
+
|
4
|
+
|
5
|
+
OperationActionT = TypeVar("OperationActionT", bound=Optional[BaseModel])
|
6
|
+
|
7
|
+
|
8
|
+
class OperationActionMixin(BaseModel, Generic[OperationActionT]):
|
9
|
+
action: OperationActionT = Field(..., description="Action.")
|
@@ -0,0 +1,230 @@
|
|
1
|
+
import traceback
|
2
|
+
from typing import Generic, Literal
|
3
|
+
from maleo.logging.enums import Level
|
4
|
+
from maleo.logging.logger import Base
|
5
|
+
from maleo.mixins.general import Success, SuccessT
|
6
|
+
from maleo.mixins.operation import (
|
7
|
+
OperationIdentifier,
|
8
|
+
OperationSummary,
|
9
|
+
OperationType,
|
10
|
+
)
|
11
|
+
from maleo.mixins.timestamp import OperationTimestampMixin
|
12
|
+
from maleo.types.base.boolean import OptionalBoolean
|
13
|
+
from maleo.types.base.dict import (
|
14
|
+
OptionalStringToStringDict,
|
15
|
+
StringToAnyDict,
|
16
|
+
StringToStringDict,
|
17
|
+
)
|
18
|
+
from maleo.utils.merger import merge_dicts
|
19
|
+
from maleo.dtos.authentication import AuthenticationT, AuthenticationMixin
|
20
|
+
from maleo.dtos.contexts.operation import OperationContext, OperationContextMixin
|
21
|
+
from maleo.dtos.contexts.request import GenericRequestContextT, RequestContextMixin
|
22
|
+
from maleo.dtos.contexts.response import ResponseContextT, ResponseContextMixin
|
23
|
+
from maleo.dtos.contexts.service import ServiceContext, ServiceContextMixin
|
24
|
+
from maleo.dtos.error import GenericErrorT, ErrorT, ErrorMixin
|
25
|
+
from maleo.dtos.resource import ResourceT, ResourceMixin
|
26
|
+
from ..response import ResponseT, ResponseMixin
|
27
|
+
from .action import (
|
28
|
+
OperationActionMixin,
|
29
|
+
OperationActionT,
|
30
|
+
)
|
31
|
+
|
32
|
+
|
33
|
+
class BaseOperation(
|
34
|
+
ResponseMixin[ResponseT],
|
35
|
+
ResponseContextMixin[ResponseContextT],
|
36
|
+
OperationActionMixin[OperationActionT],
|
37
|
+
AuthenticationMixin[AuthenticationT],
|
38
|
+
RequestContextMixin[GenericRequestContextT],
|
39
|
+
ErrorMixin[GenericErrorT],
|
40
|
+
Success[SuccessT],
|
41
|
+
ResourceMixin[ResourceT],
|
42
|
+
OperationSummary,
|
43
|
+
OperationTimestampMixin,
|
44
|
+
OperationContextMixin[OperationContext],
|
45
|
+
OperationType,
|
46
|
+
OperationIdentifier,
|
47
|
+
ServiceContextMixin[ServiceContext],
|
48
|
+
Generic[
|
49
|
+
ResourceT,
|
50
|
+
SuccessT,
|
51
|
+
GenericErrorT,
|
52
|
+
GenericRequestContextT,
|
53
|
+
AuthenticationT,
|
54
|
+
OperationActionT,
|
55
|
+
ResponseContextT,
|
56
|
+
ResponseT,
|
57
|
+
],
|
58
|
+
):
|
59
|
+
@property
|
60
|
+
def log_message(self) -> str:
|
61
|
+
message = f"Operation {self.id} - {self.type} - "
|
62
|
+
|
63
|
+
success_information = f"{'success' if self.success else 'failed'}"
|
64
|
+
|
65
|
+
if self.response_context is not None:
|
66
|
+
success_information += f" {self.response_context.status_code}"
|
67
|
+
|
68
|
+
message += f"{success_information} - "
|
69
|
+
|
70
|
+
if self.request_context is not None:
|
71
|
+
message += (
|
72
|
+
f"{self.request_context.method} {self.request_context.url} - "
|
73
|
+
f"IP: {self.request_context.ip_address} - "
|
74
|
+
)
|
75
|
+
|
76
|
+
if self.authentication is None:
|
77
|
+
authentication = "No Authentication"
|
78
|
+
else:
|
79
|
+
# * In this line, 'is_authenticated' is not detected
|
80
|
+
# * due to the use of generic, but this property exists
|
81
|
+
if not self.authentication.user.is_authenticated:
|
82
|
+
authentication = "Unauthenticated"
|
83
|
+
else:
|
84
|
+
# * In this line, 'display_name' and 'identity' is not detected
|
85
|
+
# * due to the use of generic, but this property exists
|
86
|
+
authentication = (
|
87
|
+
"Authenticated | "
|
88
|
+
f"Username: {self.authentication.user.display_name} | "
|
89
|
+
f"Email: {self.authentication.user.identity}"
|
90
|
+
)
|
91
|
+
|
92
|
+
message += f"{authentication} - "
|
93
|
+
message += self.summary
|
94
|
+
|
95
|
+
return message
|
96
|
+
|
97
|
+
@property
|
98
|
+
def labels(self) -> StringToStringDict:
|
99
|
+
labels = {
|
100
|
+
"service": self.service_context.key,
|
101
|
+
"environment": self.service_context.environment,
|
102
|
+
"operation_id": str(self.id),
|
103
|
+
"operation_type": self.type,
|
104
|
+
"success": "true" if self.success else "false",
|
105
|
+
}
|
106
|
+
|
107
|
+
if self.request_context is not None:
|
108
|
+
labels["method"] = self.request_context.method
|
109
|
+
labels["url"] = self.request_context.url
|
110
|
+
if self.response_context is not None:
|
111
|
+
labels["status_code"] = str(self.response_context.status_code)
|
112
|
+
|
113
|
+
return labels
|
114
|
+
|
115
|
+
def log_labels(
|
116
|
+
self,
|
117
|
+
*,
|
118
|
+
additional_labels: OptionalStringToStringDict = None,
|
119
|
+
override_labels: OptionalStringToStringDict = None,
|
120
|
+
) -> StringToStringDict:
|
121
|
+
if override_labels is not None:
|
122
|
+
return override_labels
|
123
|
+
|
124
|
+
labels = self.labels
|
125
|
+
if additional_labels is not None:
|
126
|
+
for k, v in additional_labels.items():
|
127
|
+
if k in labels.keys():
|
128
|
+
raise ValueError(
|
129
|
+
f"Key '{k}' already exist in labels, override the labels if necessary"
|
130
|
+
)
|
131
|
+
labels[k] = v
|
132
|
+
labels = merge_dicts(labels, additional_labels)
|
133
|
+
return labels
|
134
|
+
|
135
|
+
def log_extra(
|
136
|
+
self,
|
137
|
+
*,
|
138
|
+
additional_extra: OptionalStringToStringDict = None,
|
139
|
+
override_extra: OptionalStringToStringDict = None,
|
140
|
+
additional_labels: OptionalStringToStringDict = None,
|
141
|
+
override_labels: OptionalStringToStringDict = None,
|
142
|
+
) -> StringToAnyDict:
|
143
|
+
labels = self.log_labels(
|
144
|
+
additional_labels=additional_labels, override_labels=override_labels
|
145
|
+
)
|
146
|
+
|
147
|
+
if override_extra is not None:
|
148
|
+
extra = override_extra
|
149
|
+
else:
|
150
|
+
extra = {"json_fields": self.model_dump(mode="json"), "labels": labels}
|
151
|
+
if additional_extra is not None:
|
152
|
+
extra = merge_dicts(extra, additional_extra)
|
153
|
+
|
154
|
+
return extra
|
155
|
+
|
156
|
+
def log(
|
157
|
+
self,
|
158
|
+
logger: Base,
|
159
|
+
level: Level,
|
160
|
+
*,
|
161
|
+
exc_info: OptionalBoolean = None,
|
162
|
+
additional_extra: OptionalStringToStringDict = None,
|
163
|
+
override_extra: OptionalStringToStringDict = None,
|
164
|
+
additional_labels: OptionalStringToStringDict = None,
|
165
|
+
override_labels: OptionalStringToStringDict = None,
|
166
|
+
):
|
167
|
+
try:
|
168
|
+
message = self.log_message
|
169
|
+
extra = self.log_extra(
|
170
|
+
additional_extra=additional_extra,
|
171
|
+
override_extra=override_extra,
|
172
|
+
additional_labels=additional_labels,
|
173
|
+
override_labels=override_labels,
|
174
|
+
)
|
175
|
+
logger.log(
|
176
|
+
level,
|
177
|
+
message,
|
178
|
+
exc_info=exc_info,
|
179
|
+
extra=extra,
|
180
|
+
)
|
181
|
+
except Exception:
|
182
|
+
print("Failed logging operation:\n", traceback.format_exc())
|
183
|
+
|
184
|
+
|
185
|
+
class FailedBaseOperation(
|
186
|
+
BaseOperation[
|
187
|
+
ResourceT,
|
188
|
+
Literal[False],
|
189
|
+
ErrorT,
|
190
|
+
GenericRequestContextT,
|
191
|
+
AuthenticationT,
|
192
|
+
OperationActionT,
|
193
|
+
ResponseContextT,
|
194
|
+
ResponseT,
|
195
|
+
],
|
196
|
+
Generic[
|
197
|
+
ResourceT,
|
198
|
+
ErrorT,
|
199
|
+
GenericRequestContextT,
|
200
|
+
AuthenticationT,
|
201
|
+
OperationActionT,
|
202
|
+
ResponseContextT,
|
203
|
+
ResponseT,
|
204
|
+
],
|
205
|
+
):
|
206
|
+
success: Literal[False] = False
|
207
|
+
|
208
|
+
|
209
|
+
class SuccessfulBaseOperation(
|
210
|
+
BaseOperation[
|
211
|
+
ResourceT,
|
212
|
+
Literal[True],
|
213
|
+
None,
|
214
|
+
GenericRequestContextT,
|
215
|
+
AuthenticationT,
|
216
|
+
OperationActionT,
|
217
|
+
ResponseContextT,
|
218
|
+
ResponseT,
|
219
|
+
],
|
220
|
+
Generic[
|
221
|
+
ResourceT,
|
222
|
+
GenericRequestContextT,
|
223
|
+
AuthenticationT,
|
224
|
+
OperationActionT,
|
225
|
+
ResponseContextT,
|
226
|
+
ResponseT,
|
227
|
+
],
|
228
|
+
):
|
229
|
+
success: Literal[True] = True
|
230
|
+
error: None = None
|
@@ -0,0 +1,128 @@
|
|
1
|
+
from typing import Generic, Literal
|
2
|
+
from maleo.enums.operation import OperationType
|
3
|
+
from maleo.mixins.general import SuccessT
|
4
|
+
from maleo.dtos.authentication import AuthenticationT, OptionalAuthentication
|
5
|
+
from maleo.dtos.error import GenericErrorT, ErrorT
|
6
|
+
from maleo.dtos.contexts.request import RequestContext
|
7
|
+
from maleo.dtos.contexts.response import ResponseContext
|
8
|
+
from ..response import ResponseT, ErrorResponseT, SuccessResponseT
|
9
|
+
from .base import BaseOperation
|
10
|
+
from .resource import (
|
11
|
+
CreateResourceOperationAction,
|
12
|
+
ReadResourceOperationAction,
|
13
|
+
UpdateResourceOperationAction,
|
14
|
+
DeleteResourceOperationAction,
|
15
|
+
ResourceOperationActionT,
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
class RequestOperation(
|
20
|
+
BaseOperation[
|
21
|
+
None,
|
22
|
+
SuccessT,
|
23
|
+
GenericErrorT,
|
24
|
+
RequestContext,
|
25
|
+
OptionalAuthentication,
|
26
|
+
ResourceOperationActionT,
|
27
|
+
ResponseContext,
|
28
|
+
ResponseT,
|
29
|
+
],
|
30
|
+
Generic[
|
31
|
+
SuccessT,
|
32
|
+
GenericErrorT,
|
33
|
+
ResourceOperationActionT,
|
34
|
+
ResponseT,
|
35
|
+
],
|
36
|
+
):
|
37
|
+
type: OperationType = OperationType.REQUEST
|
38
|
+
resource: None = None
|
39
|
+
|
40
|
+
|
41
|
+
class FailedRequestOperation(
|
42
|
+
RequestOperation[
|
43
|
+
Literal[False],
|
44
|
+
ErrorT,
|
45
|
+
ResourceOperationActionT,
|
46
|
+
ErrorResponseT,
|
47
|
+
],
|
48
|
+
Generic[
|
49
|
+
ErrorT,
|
50
|
+
ResourceOperationActionT,
|
51
|
+
ErrorResponseT,
|
52
|
+
],
|
53
|
+
):
|
54
|
+
success: Literal[False] = False
|
55
|
+
summary: str = "Failed processing request"
|
56
|
+
|
57
|
+
|
58
|
+
class CreateFailedRequestOperation(
|
59
|
+
FailedRequestOperation[ErrorT, CreateResourceOperationAction, ErrorResponseT],
|
60
|
+
Generic[ErrorT, ErrorResponseT],
|
61
|
+
):
|
62
|
+
pass
|
63
|
+
|
64
|
+
|
65
|
+
class ReadFailedRequestOperation(
|
66
|
+
FailedRequestOperation[ErrorT, CreateResourceOperationAction, ErrorResponseT],
|
67
|
+
Generic[ErrorT, ErrorResponseT],
|
68
|
+
):
|
69
|
+
pass
|
70
|
+
|
71
|
+
|
72
|
+
class UpdateFailedRequestOperation(
|
73
|
+
FailedRequestOperation[ErrorT, UpdateResourceOperationAction, ErrorResponseT],
|
74
|
+
Generic[ErrorT, AuthenticationT, ErrorResponseT],
|
75
|
+
):
|
76
|
+
pass
|
77
|
+
|
78
|
+
|
79
|
+
class DeleteFailedRequestOperation(
|
80
|
+
FailedRequestOperation[ErrorT, DeleteResourceOperationAction, ErrorResponseT],
|
81
|
+
Generic[ErrorT, AuthenticationT, ErrorResponseT],
|
82
|
+
):
|
83
|
+
pass
|
84
|
+
|
85
|
+
|
86
|
+
class SuccessfulRequestOperation(
|
87
|
+
RequestOperation[
|
88
|
+
Literal[True],
|
89
|
+
None,
|
90
|
+
ResourceOperationActionT,
|
91
|
+
SuccessResponseT,
|
92
|
+
],
|
93
|
+
Generic[
|
94
|
+
ResourceOperationActionT,
|
95
|
+
SuccessResponseT,
|
96
|
+
],
|
97
|
+
):
|
98
|
+
success: Literal[True] = True
|
99
|
+
error: None = None
|
100
|
+
summary: str = "Successfully processed request"
|
101
|
+
|
102
|
+
|
103
|
+
class CreateSuccessfulRequestOperation(
|
104
|
+
SuccessfulRequestOperation[CreateResourceOperationAction, SuccessResponseT],
|
105
|
+
Generic[AuthenticationT, SuccessResponseT],
|
106
|
+
):
|
107
|
+
pass
|
108
|
+
|
109
|
+
|
110
|
+
class ReadSuccessfulRequestOperation(
|
111
|
+
SuccessfulRequestOperation[ReadResourceOperationAction, SuccessResponseT],
|
112
|
+
Generic[AuthenticationT, SuccessResponseT],
|
113
|
+
):
|
114
|
+
pass
|
115
|
+
|
116
|
+
|
117
|
+
class UpdateSuccessfulRequestOperation(
|
118
|
+
SuccessfulRequestOperation[UpdateResourceOperationAction, SuccessResponseT],
|
119
|
+
Generic[AuthenticationT, SuccessResponseT],
|
120
|
+
):
|
121
|
+
pass
|
122
|
+
|
123
|
+
|
124
|
+
class DeleteSuccessfulRequestOperation(
|
125
|
+
SuccessfulRequestOperation[DeleteResourceOperationAction, SuccessResponseT],
|
126
|
+
Generic[AuthenticationT, SuccessResponseT],
|
127
|
+
):
|
128
|
+
pass
|