DefStream 0.1.2__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.
- DefStream/Broker/Configuration.py +18 -0
- DefStream/Broker/Connection.py +97 -0
- DefStream/Broker/Consumer.py +59 -0
- DefStream/Broker/Errors.py +14 -0
- DefStream/Broker/Event.py +35 -0
- DefStream/Broker/Implements/__init__.py +1 -0
- DefStream/Broker/Policies.py +25 -0
- DefStream/Broker/Protocol.py +45 -0
- DefStream/Broker/__init__.py +47 -0
- DefStream/Descriptor/DataObject.py +384 -0
- DefStream/Descriptor/Types.py +229 -0
- DefStream/Descriptor/Value.py +132 -0
- DefStream/Descriptor/__init__.py +172 -0
- DefStream/Inspector/Extension.py +69 -0
- DefStream/Inspector/Extensions/Console.html +373 -0
- DefStream/Inspector/Extensions/Console.py +396 -0
- DefStream/Inspector/Extensions/Dashboard.html +206 -0
- DefStream/Inspector/Extensions/Dashboard.py +114 -0
- DefStream/Inspector/Extensions/HealthCheck.py +92 -0
- DefStream/Inspector/Extensions/Metrics.py +281 -0
- DefStream/Inspector/Extensions/Specifications.py +160 -0
- DefStream/Inspector/Extensions/__init__.py +13 -0
- DefStream/Inspector/Inspector.py +216 -0
- DefStream/Inspector/Response.py +14 -0
- DefStream/Inspector/__init__.py +9 -0
- DefStream/Validator/Pattern.py +36 -0
- DefStream/Validator/Patterns/Array.py +30 -0
- DefStream/Validator/Patterns/Common.py +93 -0
- DefStream/Validator/Patterns/Compare.py +180 -0
- DefStream/Validator/Patterns/Condition.py +60 -0
- DefStream/Validator/Patterns/DataObject.py +85 -0
- DefStream/Validator/Patterns/DateTime.py +111 -0
- DefStream/Validator/Patterns/Number.py +43 -0
- DefStream/Validator/Patterns/Object.py +150 -0
- DefStream/Validator/Patterns/Size.py +110 -0
- DefStream/Validator/Patterns/String.py +85 -0
- DefStream/Validator/Patterns/Type.py +350 -0
- DefStream/Validator/Patterns/__init__.py +137 -0
- DefStream/Validator/Validate.py +29 -0
- DefStream/Validator/Validator.py +30 -0
- DefStream/Validator/__init__.py +11 -0
- DefStream/Worker/Executor.py +298 -0
- DefStream/Worker/Message.py +103 -0
- DefStream/Worker/Pool.py +203 -0
- DefStream/Worker/Run.py +187 -0
- DefStream/Worker/Specification.py +91 -0
- DefStream/Worker/Worker.py +321 -0
- DefStream/Worker/__init__.py +49 -0
- DefStream/__init__.py +0 -0
- defstream-0.1.2.dist-info/METADATA +1197 -0
- defstream-0.1.2.dist-info/RECORD +54 -0
- defstream-0.1.2.dist-info/WHEEL +5 -0
- defstream-0.1.2.dist-info/licenses/LICENSE +674 -0
- defstream-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
from typing import Any, Iterator, KeysView, ItemsView, ValuesView
|
|
8
|
+
from typing import Optional, Sequence, Dict, Union, Iterable, Tuple
|
|
9
|
+
from abc import ABCMeta, ABC
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
'Type',
|
|
13
|
+
'Value',
|
|
14
|
+
'Condition',
|
|
15
|
+
'Schema',
|
|
16
|
+
'OneOf',
|
|
17
|
+
'AllOf',
|
|
18
|
+
'TypeMapper',
|
|
19
|
+
'TypeEncoder',
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Descriptor(Mapping):
|
|
24
|
+
def __init__(self, **kwargs: Dict[str, Union['Value', 'Schema']]):
|
|
25
|
+
self.__properties__ = kwargs
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
def __getitem__(self, key: Any) -> Any:
|
|
29
|
+
return self.__properties__.__getitem__(key)
|
|
30
|
+
|
|
31
|
+
def __setitem__(self, key: Any, value: Any) -> None:
|
|
32
|
+
return self.__properties__.__setitem__(key, value)
|
|
33
|
+
|
|
34
|
+
def __delitem__(self, key: Any) -> None:
|
|
35
|
+
return self.__properties__.__delitem__(key)
|
|
36
|
+
|
|
37
|
+
def __iter__(self) -> Iterator:
|
|
38
|
+
return self.__properties__.__iter__()
|
|
39
|
+
|
|
40
|
+
def __len__(self) -> int:
|
|
41
|
+
return self.__properties__.__len__()
|
|
42
|
+
|
|
43
|
+
def __contains__(self, key: object) -> bool:
|
|
44
|
+
return self.__properties__.__contains__(key)
|
|
45
|
+
|
|
46
|
+
def keys(self) -> KeysView:
|
|
47
|
+
return self.__properties__.keys()
|
|
48
|
+
|
|
49
|
+
def items(self) -> ItemsView:
|
|
50
|
+
return self.__properties__.items()
|
|
51
|
+
|
|
52
|
+
def values(self) -> ValuesView:
|
|
53
|
+
return self.__properties__.values()
|
|
54
|
+
|
|
55
|
+
def __eq__(self, other: object) -> bool:
|
|
56
|
+
return self.__properties__.__eq__(other)
|
|
57
|
+
|
|
58
|
+
def __ne__(self, value: object) -> bool:
|
|
59
|
+
return self.__properties__.__ne__(value)
|
|
60
|
+
|
|
61
|
+
def get(self, key: object) -> Any:
|
|
62
|
+
return self.__properties__.get(key)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Type(str, Enum):
|
|
66
|
+
Boolean = 'boolean'
|
|
67
|
+
Integer = 'integer'
|
|
68
|
+
Number = 'number'
|
|
69
|
+
String = 'string'
|
|
70
|
+
Array = 'array'
|
|
71
|
+
Object = 'object'
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class Value(Descriptor):
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
type: Type,
|
|
78
|
+
description: str = None,
|
|
79
|
+
format: str = None,
|
|
80
|
+
min: Any = None,
|
|
81
|
+
max: Any = None,
|
|
82
|
+
default: Any = None,
|
|
83
|
+
enum: Optional[Iterable[Any]] = None,
|
|
84
|
+
required: bool = True,
|
|
85
|
+
):
|
|
86
|
+
super().__init__(type=type)
|
|
87
|
+
if description: self['description'] = description
|
|
88
|
+
if format: self['format'] = format
|
|
89
|
+
if min is not None: self['minimum'] = min
|
|
90
|
+
if max is not None: self['maximum'] = max
|
|
91
|
+
if not required: self['default'] = default
|
|
92
|
+
if enum: self['enum'] = enum
|
|
93
|
+
self.required = required
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class Condition(ABC):
|
|
98
|
+
def __init__(self, *args):
|
|
99
|
+
self.args = args
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Schema(object):
|
|
104
|
+
def __init__(
|
|
105
|
+
self,
|
|
106
|
+
name: str,
|
|
107
|
+
format: Union[Value, Condition] = None,
|
|
108
|
+
):
|
|
109
|
+
self.name = name
|
|
110
|
+
self.format = format
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class OneOf(Condition):
|
|
115
|
+
def __init__(self, *args: Iterable[Union[Value, Schema]], discriminator: str = None, required: bool = True):
|
|
116
|
+
self.args = args
|
|
117
|
+
self.discriminator = discriminator
|
|
118
|
+
self.required = required
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class AllOf(Condition): pass
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class TypeMapper(metaclass=ABCMeta):
|
|
126
|
+
def __call__(self, o: type) -> Tuple[Value, Dict[str, Any]]:
|
|
127
|
+
raise NotImplementedError('{} must be implemented __call__'.format(self.__class__.__name__))
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class TypeEncoder(metaclass=ABCMeta):
|
|
131
|
+
def __call__(self, o: Any) -> Any:
|
|
132
|
+
raise NotImplementedError('{} must be implemented __call__'.format(self.__class__.__name__))
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from collections.abc import (
|
|
2
|
+
Mapping,
|
|
3
|
+
Sequence,
|
|
4
|
+
)
|
|
5
|
+
from dataclasses import is_dataclass
|
|
6
|
+
from json import (
|
|
7
|
+
dumps,
|
|
8
|
+
loads,
|
|
9
|
+
)
|
|
10
|
+
from typing import (
|
|
11
|
+
Any,
|
|
12
|
+
Optional,
|
|
13
|
+
Type,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .Value import (
|
|
17
|
+
Value,
|
|
18
|
+
Condition,
|
|
19
|
+
Schema,
|
|
20
|
+
OneOf,
|
|
21
|
+
AllOf,
|
|
22
|
+
TypeMapper,
|
|
23
|
+
TypeEncoder,
|
|
24
|
+
)
|
|
25
|
+
from .Types import (
|
|
26
|
+
Boolean,
|
|
27
|
+
IntegerFormat,
|
|
28
|
+
Integer,
|
|
29
|
+
NumberFormat,
|
|
30
|
+
Number,
|
|
31
|
+
StringFormat,
|
|
32
|
+
String,
|
|
33
|
+
Binary,
|
|
34
|
+
BinaryBase64Encoded,
|
|
35
|
+
Array,
|
|
36
|
+
Object,
|
|
37
|
+
Properties,
|
|
38
|
+
)
|
|
39
|
+
from .DataObject import (
|
|
40
|
+
DataObjectToSchema,
|
|
41
|
+
DataObjectToObject,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
__all__ = (
|
|
45
|
+
'Value',
|
|
46
|
+
'Condition',
|
|
47
|
+
'Schema',
|
|
48
|
+
'OneOf',
|
|
49
|
+
'AllOf',
|
|
50
|
+
'TypeMapper',
|
|
51
|
+
'TypeEncoder',
|
|
52
|
+
'Boolean',
|
|
53
|
+
'IntegerFormat',
|
|
54
|
+
'Integer',
|
|
55
|
+
'NumberFormat',
|
|
56
|
+
'Number',
|
|
57
|
+
'StringFormat',
|
|
58
|
+
'String',
|
|
59
|
+
'Binary',
|
|
60
|
+
'BinaryBase64Encoded',
|
|
61
|
+
'Array',
|
|
62
|
+
'Object',
|
|
63
|
+
'Properties',
|
|
64
|
+
'ToSchema',
|
|
65
|
+
'DumpSchema',
|
|
66
|
+
'ToObject',
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def schema_value(
|
|
71
|
+
value: Any,
|
|
72
|
+
) -> Any:
|
|
73
|
+
if isinstance(
|
|
74
|
+
value,
|
|
75
|
+
Schema,
|
|
76
|
+
):
|
|
77
|
+
return schema_value(value.format)
|
|
78
|
+
if isinstance(
|
|
79
|
+
value,
|
|
80
|
+
Condition,
|
|
81
|
+
):
|
|
82
|
+
if isinstance(
|
|
83
|
+
value,
|
|
84
|
+
OneOf,
|
|
85
|
+
):
|
|
86
|
+
key = 'oneOf'
|
|
87
|
+
elif isinstance(
|
|
88
|
+
value,
|
|
89
|
+
AllOf,
|
|
90
|
+
):
|
|
91
|
+
key = 'allOf'
|
|
92
|
+
else:
|
|
93
|
+
raise TypeError('Unsupported schema condition: ' + type(value).__name__)
|
|
94
|
+
return {key: [schema_value(arg) for arg in value.args]}
|
|
95
|
+
if isinstance(
|
|
96
|
+
value,
|
|
97
|
+
Mapping,
|
|
98
|
+
):
|
|
99
|
+
return {
|
|
100
|
+
key: schema_value(item) for key, item in value.items()
|
|
101
|
+
}
|
|
102
|
+
if isinstance(
|
|
103
|
+
value,
|
|
104
|
+
Sequence,
|
|
105
|
+
) and not isinstance(
|
|
106
|
+
value,
|
|
107
|
+
(
|
|
108
|
+
str,
|
|
109
|
+
bytes,
|
|
110
|
+
bytearray,
|
|
111
|
+
),
|
|
112
|
+
):
|
|
113
|
+
return [schema_value(item) for item in value]
|
|
114
|
+
if value is None or isinstance(
|
|
115
|
+
value,
|
|
116
|
+
(
|
|
117
|
+
str,
|
|
118
|
+
int,
|
|
119
|
+
float,
|
|
120
|
+
bool,
|
|
121
|
+
),
|
|
122
|
+
):
|
|
123
|
+
return value
|
|
124
|
+
raise TypeError('Unsupported schema value: ' + type(value).__name__)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def DumpSchema(
|
|
128
|
+
o: Schema,
|
|
129
|
+
) -> dict:
|
|
130
|
+
if not isinstance(
|
|
131
|
+
o,
|
|
132
|
+
Schema,
|
|
133
|
+
):
|
|
134
|
+
raise TypeError('A Schema is required')
|
|
135
|
+
result = schema_value(o)
|
|
136
|
+
if not isinstance(
|
|
137
|
+
result,
|
|
138
|
+
dict,
|
|
139
|
+
):
|
|
140
|
+
raise TypeError('A schema must describe an object, value or condition')
|
|
141
|
+
return loads(dumps(
|
|
142
|
+
result,
|
|
143
|
+
allow_nan=False,
|
|
144
|
+
))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def ToSchema(
|
|
148
|
+
o: Type[object],
|
|
149
|
+
description: Optional[str] = None,
|
|
150
|
+
typedef: Optional[TypeMapper] = None,
|
|
151
|
+
) -> Schema:
|
|
152
|
+
if not isinstance(
|
|
153
|
+
o,
|
|
154
|
+
type,
|
|
155
|
+
) or not is_dataclass(o):
|
|
156
|
+
raise TypeError('A dataclass type is required')
|
|
157
|
+
return DataObjectToSchema(mapper=typedef)(
|
|
158
|
+
o,
|
|
159
|
+
description,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def ToObject(
|
|
164
|
+
o: object,
|
|
165
|
+
typeenc: Optional[TypeEncoder] = None,
|
|
166
|
+
) -> dict:
|
|
167
|
+
if isinstance(
|
|
168
|
+
o,
|
|
169
|
+
type,
|
|
170
|
+
) or not is_dataclass(o):
|
|
171
|
+
raise TypeError('A dataclass instance is required')
|
|
172
|
+
return DataObjectToObject(encoder=typeenc)(o)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from abc import (
|
|
2
|
+
ABC,
|
|
3
|
+
abstractmethod,
|
|
4
|
+
)
|
|
5
|
+
from typing import (
|
|
6
|
+
Optional,
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from .Response import Response
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .Inspector import Inspector
|
|
14
|
+
|
|
15
|
+
__all__ = (
|
|
16
|
+
'Extension',
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Extension(ABC):
|
|
21
|
+
methods = (
|
|
22
|
+
'GET',
|
|
23
|
+
'HEAD',
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
path: str,
|
|
29
|
+
):
|
|
30
|
+
if not isinstance(
|
|
31
|
+
path,
|
|
32
|
+
str,
|
|
33
|
+
) or not path.startswith('/') or '?' in path or '#' in path:
|
|
34
|
+
raise ValueError('An absolute HTTP path without a query or fragment is required')
|
|
35
|
+
self.path = path
|
|
36
|
+
|
|
37
|
+
def start(
|
|
38
|
+
self,
|
|
39
|
+
inspector: 'Inspector',
|
|
40
|
+
) -> None:
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
def begin(
|
|
44
|
+
self,
|
|
45
|
+
task: str,
|
|
46
|
+
) -> object:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
def end(
|
|
50
|
+
self,
|
|
51
|
+
task: str,
|
|
52
|
+
context: object,
|
|
53
|
+
success: Optional[bool],
|
|
54
|
+
) -> None:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
def handle(
|
|
58
|
+
self,
|
|
59
|
+
inspector: 'Inspector',
|
|
60
|
+
environ: dict,
|
|
61
|
+
) -> Response:
|
|
62
|
+
return self(inspector)
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def __call__(
|
|
66
|
+
self,
|
|
67
|
+
inspector: 'Inspector',
|
|
68
|
+
) -> Response:
|
|
69
|
+
raise NotImplementedError
|