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.
Files changed (54) hide show
  1. DefStream/Broker/Configuration.py +18 -0
  2. DefStream/Broker/Connection.py +97 -0
  3. DefStream/Broker/Consumer.py +59 -0
  4. DefStream/Broker/Errors.py +14 -0
  5. DefStream/Broker/Event.py +35 -0
  6. DefStream/Broker/Implements/__init__.py +1 -0
  7. DefStream/Broker/Policies.py +25 -0
  8. DefStream/Broker/Protocol.py +45 -0
  9. DefStream/Broker/__init__.py +47 -0
  10. DefStream/Descriptor/DataObject.py +384 -0
  11. DefStream/Descriptor/Types.py +229 -0
  12. DefStream/Descriptor/Value.py +132 -0
  13. DefStream/Descriptor/__init__.py +172 -0
  14. DefStream/Inspector/Extension.py +69 -0
  15. DefStream/Inspector/Extensions/Console.html +373 -0
  16. DefStream/Inspector/Extensions/Console.py +396 -0
  17. DefStream/Inspector/Extensions/Dashboard.html +206 -0
  18. DefStream/Inspector/Extensions/Dashboard.py +114 -0
  19. DefStream/Inspector/Extensions/HealthCheck.py +92 -0
  20. DefStream/Inspector/Extensions/Metrics.py +281 -0
  21. DefStream/Inspector/Extensions/Specifications.py +160 -0
  22. DefStream/Inspector/Extensions/__init__.py +13 -0
  23. DefStream/Inspector/Inspector.py +216 -0
  24. DefStream/Inspector/Response.py +14 -0
  25. DefStream/Inspector/__init__.py +9 -0
  26. DefStream/Validator/Pattern.py +36 -0
  27. DefStream/Validator/Patterns/Array.py +30 -0
  28. DefStream/Validator/Patterns/Common.py +93 -0
  29. DefStream/Validator/Patterns/Compare.py +180 -0
  30. DefStream/Validator/Patterns/Condition.py +60 -0
  31. DefStream/Validator/Patterns/DataObject.py +85 -0
  32. DefStream/Validator/Patterns/DateTime.py +111 -0
  33. DefStream/Validator/Patterns/Number.py +43 -0
  34. DefStream/Validator/Patterns/Object.py +150 -0
  35. DefStream/Validator/Patterns/Size.py +110 -0
  36. DefStream/Validator/Patterns/String.py +85 -0
  37. DefStream/Validator/Patterns/Type.py +350 -0
  38. DefStream/Validator/Patterns/__init__.py +137 -0
  39. DefStream/Validator/Validate.py +29 -0
  40. DefStream/Validator/Validator.py +30 -0
  41. DefStream/Validator/__init__.py +11 -0
  42. DefStream/Worker/Executor.py +298 -0
  43. DefStream/Worker/Message.py +103 -0
  44. DefStream/Worker/Pool.py +203 -0
  45. DefStream/Worker/Run.py +187 -0
  46. DefStream/Worker/Specification.py +91 -0
  47. DefStream/Worker/Worker.py +321 -0
  48. DefStream/Worker/__init__.py +49 -0
  49. DefStream/__init__.py +0 -0
  50. defstream-0.1.2.dist-info/METADATA +1197 -0
  51. defstream-0.1.2.dist-info/RECORD +54 -0
  52. defstream-0.1.2.dist-info/WHEEL +5 -0
  53. defstream-0.1.2.dist-info/licenses/LICENSE +674 -0
  54. defstream-0.1.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,384 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from .Value import (
4
+ Value,
5
+ Schema,
6
+ OneOf,
7
+ TypeMapper,
8
+ TypeEncoder,
9
+ )
10
+
11
+ from .Types import (
12
+ Boolean,
13
+ Integer,
14
+ Number,
15
+ String,
16
+ Binary,
17
+ Array,
18
+ Object,
19
+ Properties,
20
+ )
21
+
22
+ from dataclasses import is_dataclass, MISSING, asdict
23
+ from json import dumps, loads
24
+ from typing import (
25
+ Type,
26
+ Any,
27
+ Union,
28
+ Sequence,
29
+ Iterable,
30
+ Annotated,
31
+ get_origin,
32
+ get_args,
33
+ get_type_hints,
34
+ ForwardRef,
35
+ )
36
+
37
+ __all__ = (
38
+ 'SchemaToDataObject',
39
+ 'DataObjectToSchema',
40
+ 'DataObjectToObject',
41
+ )
42
+
43
+
44
+ def SchemaToDataObject(o: Schema, name: str = None) -> object:
45
+ # TODO : make dataclass according to schema dynamically
46
+ raise NotImplementedError('SchemaToDataObject is not implemented yet')
47
+
48
+
49
+ class DataObjectToSchema(object):
50
+ def __init__(self, mapper: TypeMapper = None):
51
+ self.mapper = mapper
52
+ return
53
+ def __value__(
54
+ self,
55
+ o: type,
56
+ format: Union[type, Sequence[type]] = None,
57
+ description: str = None,
58
+ required: bool = True,
59
+ default: Any = MISSING,
60
+ metadata: Any = None,
61
+ ) -> Union[Value, Schema]:
62
+ args = get_args(o)
63
+ o = get_origin(o) if get_origin(o) else o
64
+ if args:
65
+ if len(args) == 1:
66
+ if o is list:
67
+ return self.__value__(
68
+ list,
69
+ format=args[0],
70
+ description=description,
71
+ required=required,
72
+ default=default,
73
+ metadata=metadata,
74
+ )
75
+ if o is tuple:
76
+ return self.__value__(
77
+ tuple,
78
+ format=args[0],
79
+ description=description,
80
+ required=required,
81
+ default=default,
82
+ metadata=metadata,
83
+ )
84
+ if o is set:
85
+ return self.__value__(
86
+ set,
87
+ format=args[0],
88
+ description=description,
89
+ required=required,
90
+ default=default,
91
+ metadata=metadata,
92
+ )
93
+ if o is Union:
94
+ return self.__value__(
95
+ Union,
96
+ format=args[0],
97
+ description=description,
98
+ required=required,
99
+ default=default,
100
+ metadata=metadata,
101
+ )
102
+ raise TypeError('{} is not a supported type'.format(o))
103
+ if len(args) == 2:
104
+ if o is Union:
105
+ if args[0] is type(None): # Union[type, None]
106
+ return self.__value__(
107
+ args[1],
108
+ description=description,
109
+ required=False,
110
+ default=None,
111
+ metadata=metadata,
112
+ )
113
+ if args[1] is type(None): # Union[None, type]
114
+ return self.__value__(
115
+ args[0],
116
+ description=description,
117
+ required=False,
118
+ default=None,
119
+ metadata=metadata,
120
+ )
121
+ # Union[type, type]
122
+ return self.__value__(
123
+ o,
124
+ format=(args[0], args[1]),
125
+ description=description,
126
+ required=required,
127
+ default=default,
128
+ metadata=metadata,
129
+ )
130
+ if o is dict: # Dict[type, type]
131
+ return self.__value__(
132
+ dict,
133
+ description=description,
134
+ required=required,
135
+ default=default,
136
+ metadata=metadata,
137
+ )
138
+ if o is Annotated:
139
+ if isinstance(args[1], str):
140
+ return self.__value__(
141
+ args[0],
142
+ description=args[1],
143
+ required=required,
144
+ default=default,
145
+ )
146
+ return self.__value__(
147
+ args[0],
148
+ description=description,
149
+ required=required,
150
+ default=default,
151
+ metadata=args[1],
152
+ )
153
+ raise TypeError('{} is not a supported type'.format(o))
154
+ if o is Union:
155
+ fs= [self.__value__(f) for f in args]
156
+ return OneOf(*fs, required=required)
157
+ if o is Annotated:
158
+ if isinstance(args[1], str):
159
+ return self.__value__(
160
+ args[0],
161
+ description=args[1],
162
+ required=required,
163
+ default=default,
164
+ metadata=args[2] if isinstance(args[2], dict) else args[2:],
165
+ )
166
+ if isinstance(args[2], str):
167
+ return self.__value__(
168
+ args[0],
169
+ description=args[2],
170
+ required=required,
171
+ default=default,
172
+ metadata=args[1],
173
+ )
174
+ return self.__value__(
175
+ args[0],
176
+ description=description,
177
+ required=required,
178
+ default=default,
179
+ metadata=args[1:],
180
+ )
181
+ raise TypeError('{} is not a supported type'.format(o))
182
+ if o is bool:
183
+ kwargs = {
184
+ 'description': description,
185
+ 'required': required,
186
+ }
187
+ if default is not MISSING:
188
+ kwargs['default'] = default
189
+ if metadata and isinstance(metadata, dict):
190
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
191
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
192
+ return Boolean(**kwargs)
193
+ if o is int:
194
+ kwargs = {
195
+ 'description': description,
196
+ 'required': required,
197
+ }
198
+ if default is not MISSING:
199
+ kwargs['default'] = default
200
+ if metadata and isinstance(metadata, dict):
201
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
202
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
203
+ if 'format' in metadata.keys(): kwargs['format'] = metadata['format']
204
+ if 'min' in metadata.keys(): kwargs['min'] = metadata['min']
205
+ if 'max' in metadata.keys(): kwargs['max'] = metadata['max']
206
+ if 'enum' in metadata.keys(): kwargs['enum'] = metadata['enum']
207
+ return Integer(**kwargs)
208
+ if o is float:
209
+ kwargs = {
210
+ 'description': description,
211
+ 'required': required,
212
+ }
213
+ if default is not MISSING:
214
+ kwargs['default'] = default
215
+ if metadata and isinstance(metadata, dict):
216
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
217
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
218
+ if 'format' in metadata.keys(): kwargs['format'] = metadata['format']
219
+ if 'min' in metadata.keys(): kwargs['min'] = metadata['min']
220
+ if 'max' in metadata.keys(): kwargs['max'] = metadata['max']
221
+ if 'enum' in metadata.keys(): kwargs['enum'] = metadata['enum']
222
+ return Number(**kwargs)
223
+ if o is str:
224
+ kwargs = {
225
+ 'description': description,
226
+ 'required': required,
227
+ }
228
+ if default is not MISSING:
229
+ kwargs['default'] = default
230
+ if metadata and isinstance(metadata, dict):
231
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
232
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
233
+ if 'format' in metadata.keys(): kwargs['format'] = metadata['format']
234
+ if 'min' in metadata.keys(): kwargs['min'] = metadata['min']
235
+ if 'max' in metadata.keys(): kwargs['max'] = metadata['max']
236
+ if 'enum' in metadata.keys(): kwargs['enum'] = metadata['enum']
237
+ return String(**kwargs)
238
+ if o is bytes:
239
+ kwargs = {
240
+ 'description': description,
241
+ 'required': required,
242
+ }
243
+ if default is not MISSING:
244
+ kwargs['default'] = default
245
+ if metadata and isinstance(metadata, dict):
246
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
247
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
248
+ return Binary(**kwargs)
249
+ if o is list:
250
+ kwargs = {
251
+ 'description': description,
252
+ 'required': required,
253
+ }
254
+ if default is not MISSING:
255
+ kwargs['default'] = default
256
+ if metadata and isinstance(metadata, dict):
257
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
258
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
259
+ if 'format' in metadata.keys():
260
+ if not isinstance(metadata['format'], Iterable):
261
+ metadata['format'] = [metadata['format']]
262
+ if len(metadata['format']) == 1:
263
+ metadata['format'] = self.__value__(metadata['format'][0])
264
+ fs = [self.__value__(f) for f in metadata['format']]
265
+ kwargs['format'] = OneOf(*fs)
266
+ if format:
267
+ if not isinstance(format, Iterable):
268
+ format = [format]
269
+ if len(format) == 1:
270
+ f = self.__value__(format[0])
271
+ return Array(format=f, **kwargs)
272
+ fs = [self.__value__(f) for f in format]
273
+ return Array(format=OneOf(*fs), **kwargs)
274
+ else:
275
+ return Array(**kwargs)
276
+ if o is tuple:
277
+ kwargs = {
278
+ 'description': description,
279
+ 'required': required,
280
+ }
281
+ if default is not MISSING:
282
+ kwargs['default'] = default
283
+ if metadata and isinstance(metadata, dict):
284
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
285
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
286
+ return Array(**kwargs)
287
+ if o is set:
288
+ kwargs = {
289
+ 'description': description,
290
+ 'required': required,
291
+ }
292
+ if default is not MISSING:
293
+ kwargs['default'] = default
294
+ if metadata and isinstance(metadata, dict):
295
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
296
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
297
+ return Array(**kwargs)
298
+ if o is dict:
299
+ kwargs = {
300
+ 'description': description,
301
+ 'required': required,
302
+ }
303
+ if default is not MISSING:
304
+ kwargs['default'] = default
305
+ if metadata and isinstance(metadata, dict):
306
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
307
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
308
+ return Object(**kwargs)
309
+ if o is Union:
310
+ kwargs = {}
311
+ if default is not MISSING:
312
+ kwargs['default'] = default
313
+ if not format:
314
+ raise TypeError('Union type must have format')
315
+ if not isinstance(format, Iterable):
316
+ format = [format]
317
+ return OneOf(*[self.__value__(f) for f in format], **kwargs)
318
+ if is_dataclass(o):
319
+ return self.__call__(o, required=required)
320
+ if isinstance(o, ForwardRef):
321
+ if o.__forward_arg__ in globals():
322
+ return self.__value__(globals()[o.__forward_arg__], description=description, required=required, default=default, metadata=metadata)
323
+ if o.__forward_arg__ in locals():
324
+ return self.__value__(locals()[o.__forward_arg__], description=description, required=required, default=default, metadata=metadata)
325
+ raise TypeError('Cannot resolve schema forward reference: ' + o.__forward_arg__)
326
+ if self.mapper:
327
+ V, kws = self.mapper(o)
328
+ if V:
329
+ if not issubclass(V, Value):
330
+ raise TypeError('{} is not a Value'.format(V))
331
+ kwargs = {
332
+ 'description': description,
333
+ 'required': required,
334
+ }
335
+ if default is not MISSING:
336
+ kwargs['default'] = default
337
+ if metadata and isinstance(metadata, dict):
338
+ if 'description' in metadata.keys(): kwargs['description'] = metadata['description']
339
+ if 'required' in metadata.keys(): kwargs['required'] = metadata['required']
340
+ if V in (Integer, Number, String):
341
+ if 'format' in metadata.keys(): kwargs['format'] = metadata['format']
342
+ if 'min' in metadata.keys(): kwargs['min'] = metadata['min']
343
+ if 'max' in metadata.keys(): kwargs['max'] = metadata['max']
344
+ if 'enum' in metadata.keys(): kwargs['enum'] = metadata['enum']
345
+ kwargs.update(kws)
346
+ return V(**kwargs)
347
+ raise TypeError('{} is not a supported type'.format(o))
348
+
349
+ def __call__(self, o: Type[object], description: str = None, required: bool = True) -> Schema:
350
+ if not is_dataclass(o):
351
+ raise TypeError('{} is not a DataObject(dataclass).'.format(o.__name__))
352
+ hints = get_type_hints(o, include_extras=True)
353
+ return Schema(
354
+ name=description or o.__name__,
355
+ format=Object(
356
+ description=description or o.__name__,
357
+ properties=Properties(
358
+ **{
359
+ f.name: self.__value__(
360
+ hints[f.name],
361
+ required=True if f.default is MISSING and f.default_factory is MISSING else False,
362
+ default=f.default_factory() if f.default_factory is not MISSING else f.default,
363
+ ) for f in o.__dataclass_fields__.values()
364
+ }
365
+ ),
366
+ required=required,
367
+ )
368
+ )
369
+
370
+
371
+ class DataObjectToObject(object):
372
+ def __init__(self, encoder: TypeEncoder = None):
373
+ self.encoder = encoder
374
+ return
375
+
376
+ def __call__(self, o: object):
377
+ if not is_dataclass(o):
378
+ raise TypeError('{} is not a DataObject(dataclass).'.format(o.__class__.__name__))
379
+ _ = dumps(
380
+ asdict(o),
381
+ default=self.encoder,
382
+ ensure_ascii=False,
383
+ )
384
+ return loads(_)
@@ -0,0 +1,229 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from .Value import Descriptor, Type, Value, Condition, Schema
4
+ from typing import Optional, Union, Sequence, Any, Dict, Iterable
5
+ from enum import Enum
6
+
7
+ __all__ = (
8
+ 'Boolean',
9
+ 'IntegerFormat',
10
+ 'Integer',
11
+ 'NumberFormat',
12
+ 'Number',
13
+ 'StringFormat',
14
+ 'String',
15
+ 'Binary',
16
+ 'BinaryBase64Encoded',
17
+ 'Array',
18
+ 'Object',
19
+ 'Properties',
20
+ )
21
+
22
+
23
+ class Boolean(Value):
24
+ def __init__(
25
+ self,
26
+ description: str = None,
27
+ default: Any = None,
28
+ required: bool = True,
29
+ ):
30
+ super().__init__(
31
+ type=Type.Boolean,
32
+ description=description,
33
+ default=default,
34
+ required=required,
35
+ )
36
+ return
37
+
38
+
39
+ class IntegerFormat(str, Enum):
40
+ int32 = 'int32'
41
+ int64 = 'int64'
42
+ uint32 = 'uint32'
43
+ uint64 = 'uint64'
44
+ byte = 'byte'
45
+ uuid = 'uuid'
46
+ datetime = 'date-time'
47
+ def __str__(self): return self.value
48
+
49
+
50
+ class Integer(Value):
51
+ def __init__(
52
+ self,
53
+ description: str = None,
54
+ format: Union[str, IntegerFormat] = None,
55
+ min: Any = None,
56
+ max: Any = None,
57
+ default: Any = None,
58
+ enum: Optional[Sequence[str]] = None,
59
+ required: bool = True,
60
+ ):
61
+ super().__init__(
62
+ type=Type.Integer,
63
+ description=description,
64
+ format=str(format) if format and isinstance(format, IntegerFormat) else format,
65
+ min=min,
66
+ max=max,
67
+ default=default,
68
+ enum=enum,
69
+ required=required,
70
+ )
71
+ return
72
+
73
+
74
+ class NumberFormat(str, Enum):
75
+ float = 'float'
76
+ double = 'double'
77
+ decimal = 'decimal'
78
+ def __str__(self): return self.value
79
+
80
+
81
+ class Number(Value):
82
+ def __init__(
83
+ self,
84
+ description: str = None,
85
+ format: Union[str, NumberFormat] = None,
86
+ min: Any = None,
87
+ max: Any = None,
88
+ default: Any = None,
89
+ enum: Optional[Sequence[str]] = None,
90
+ required: bool = True,
91
+ ):
92
+ super().__init__(
93
+ type=Type.Number,
94
+ description=description,
95
+ format=str(format) if format and isinstance(format, NumberFormat) else format,
96
+ min=min,
97
+ max=max,
98
+ default=default,
99
+ enum=enum,
100
+ required=required,
101
+ )
102
+ return
103
+
104
+
105
+ class StringFormat(str, Enum):
106
+ datetime = 'date-time' # date-time, ISO 8601
107
+ date = 'date' # date, ISO 8601
108
+ time = 'time' # time, ISO 8601
109
+ password = 'password' # password
110
+ byte = 'byte' # byte, base64 encoded
111
+ binary = 'binary' # binary
112
+ email = 'email' # email
113
+ uuid = 'uuid' # uuid
114
+ uri = 'uri' # uri
115
+ hostname = 'hostname' # hostname
116
+ ipv4 = 'ipv4' # ipv4
117
+ ipv6 = 'ipv6' # ipv6
118
+ regex = 'regex' # regex
119
+ xml = 'xml' # xml
120
+ def __str__(self): return self.value
121
+
122
+
123
+ class String(Value):
124
+ def __init__(
125
+ self,
126
+ description: str = None,
127
+ format: Union[str, StringFormat] = None,
128
+ min: Any = None,
129
+ max: Any = None,
130
+ default: Any = None,
131
+ enum: Optional[Sequence[str]] = None,
132
+ required: bool = True,
133
+ ):
134
+ super().__init__(
135
+ type=Type.String,
136
+ description=description,
137
+ format=str(format) if format and isinstance(format, StringFormat) else format,
138
+ min=min,
139
+ max=max,
140
+ default=default,
141
+ enum=enum,
142
+ required=required,
143
+ )
144
+ if min is not None:
145
+ del self['minimum']
146
+ self['minLength'] = min
147
+ if max is not None:
148
+ del self['maximum']
149
+ self['maxLength'] = max
150
+ return
151
+
152
+
153
+ class BinaryBase64Encoded(String):
154
+ def __init__(
155
+ self,
156
+ description: str = None,
157
+ default: str = None,
158
+ required: bool = True,
159
+ ):
160
+ super().__init__(
161
+ description=description,
162
+ format=StringFormat.byte,
163
+ default=default,
164
+ required=required,
165
+ )
166
+ return
167
+
168
+
169
+ class Binary(String):
170
+ def __init__(
171
+ self,
172
+ description: str = None,
173
+ default: bytes = None,
174
+ required: bool = True,
175
+ ):
176
+ super().__init__(
177
+ description=description,
178
+ format=StringFormat.binary,
179
+ default=default,
180
+ required=required,
181
+ )
182
+ return
183
+
184
+
185
+ class Properties(Descriptor):
186
+ def __init__(self, **kwargs: Dict[str, Union[Value, Condition, Schema]]):
187
+ for k, v in kwargs.items():
188
+ kwargs[k] = v.format if isinstance(v, Schema) else v
189
+ super().__init__(**kwargs)
190
+ return
191
+ class Object(Descriptor):
192
+ def __init__(
193
+ self,
194
+ description: Optional[str] = None,
195
+ properties: Optional[Properties] = None,
196
+ default: Dict = None,
197
+ required: bool = True,
198
+ ):
199
+ properties = properties if properties is not None else Properties()
200
+ super().__init__(
201
+ type=Type.Object,
202
+ properties=properties,
203
+ )
204
+ if description: self['description'] = description
205
+ self['required'] = []
206
+ for k, v in properties.items():
207
+ if hasattr(v, 'required') and getattr(v, 'required'):
208
+ self['required'].append(k)
209
+ if default is not None: self['default'] = default
210
+ self.required = required
211
+ return
212
+
213
+
214
+ class Array(Descriptor):
215
+ def __init__(
216
+ self,
217
+ description: str = None,
218
+ format: Optional[Union[Value, Condition, Schema]] = None,
219
+ default: Iterable = None,
220
+ required: bool = True,
221
+ ):
222
+ super().__init__(
223
+ type=Type.Array,
224
+ )
225
+ if description: self['description'] = description
226
+ if format: self['items'] = format.format if isinstance(format, Schema) else format
227
+ if default is not None: self['default'] = default
228
+ self.required = required
229
+ return