vortexpy 4.1.1__tar.gz → 4.1.3__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.
- {vortexpy-4.1.1 → vortexpy-4.1.3}/PKG-INFO +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/pyproject.toml +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleRestful.py +32 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexFactory.py +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexServer.py +6 -4
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexServerWebsocket.py +0 -7
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/__init__.py +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/json_schema_node_tuple.py +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/PKG-INFO +1 -1
- {vortexpy-4.1.1 → vortexpy-4.1.3}/README.md +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/setup.cfg +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/DataWrapTuple.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/DeferUtil.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/Jsonable.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/Payload.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadEndpoint.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadEndpointTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadEnvelope.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadFilterKeys.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadIO.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadPriority.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadResponse.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadResponseTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PayloadTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/PerformTestActionTuple.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/SerialiseUtil.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TestTuple.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/Tuple.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleAction.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleDataForTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TuplePerfTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TuplePolymorphicTupleTypeFieldArgTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleRestfulTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleSelector.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/TupleTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexAccessControlContextABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexAuthenticatorABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexClientHttp.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexClientHttpTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexClientTcp.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexClientWebsocketFactory.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexConnectionABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexEndpointPermission.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexPayloadProtocol.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexPermission.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexPermissionError.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexServerConnection.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexServerHttpResource.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexServerTcp.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexSession.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexTcpMemoryLeakPayloadTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexTcpMemoryLeakRawTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexUtil.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/VortexWritePushProducer.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/TupleDataLiveLockManager.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/TupleDataLoader.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/TupleDataLoaderDelegate.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/TupleDataLoaderTupleABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/TupleDataLoaderTuples.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/data_loader/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/event_bus/TupleChangeEventABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/event_bus/TupleChangeEventBus.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/event_bus/TupleChangeEventBusObserverABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/event_bus/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleActionProcessor.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleActionProcessorProxy.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleActionProcessorTestHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataAccessGranterABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataActionClient.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataObservableCache.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataObservableHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataObservableProxyHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataObservableTestHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataObserverClient.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/TupleDataProviderABC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/VortexJSTupleLoaderTestHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/handler/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/mypy_plugin.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/py.typed +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/GzippedDataHttpClient.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/GzippedDataHttpClientTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/GzippedPayloadHttpClient.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/RestfulHttpClient.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/RestfulHttpClientTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/RestfulResource.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/RestfulResourceTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/restful/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/rpc/RPC.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/rpc/RPCTest.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/rpc/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/sqla_orm/OrmCrudHandler.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/sqla_orm/TupleProviderForDb.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/sqla_orm/VortexTupleJson.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/sqla_orm/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/storage/TupleStorageSqlite.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/storage/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/__init__.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/constants.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/tuple_json_schema_builder.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/tuple_json_schema_test.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortex/tuple_json_schema/tuple_json_schema_test_tuples.py +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/SOURCES.txt +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/dependency_links.txt +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/entry_points.txt +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/requires.txt +0 -0
- {vortexpy-4.1.1 → vortexpy-4.1.3}/vortexpy.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vortexpy"
|
|
7
|
-
version = "4.1.
|
|
7
|
+
version = "4.1.3"
|
|
8
8
|
license = {text = "MIT"}
|
|
9
9
|
authors = [{name = "Flying Ion Pty Ltd", email = "contact@flyingion.com"}]
|
|
10
10
|
description = "Flying Ion's observable, routable, data serialisation and transport code."
|
|
@@ -19,7 +19,7 @@ from dataclasses import dataclass, field
|
|
|
19
19
|
from datetime import datetime
|
|
20
20
|
from typing import TYPE_CHECKING, Annotated, Any, NamedTuple, Optional, Type
|
|
21
21
|
|
|
22
|
-
from typing import get_args
|
|
22
|
+
from typing import Union, get_args
|
|
23
23
|
from typing import get_origin
|
|
24
24
|
from typing import get_type_hints
|
|
25
25
|
|
|
@@ -256,6 +256,24 @@ class TupleRestfulConverter:
|
|
|
256
256
|
|
|
257
257
|
return True
|
|
258
258
|
|
|
259
|
+
@classmethod
|
|
260
|
+
def _nestedTupleTypeFromHint(cls, typeHint: Any) -> Any | None:
|
|
261
|
+
"""Return nested tuple class for a field hint, including ``X | None`` unions."""
|
|
262
|
+
if hasattr(typeHint, "__tupleType__"):
|
|
263
|
+
return typeHint
|
|
264
|
+
|
|
265
|
+
unionArgs = get_args(typeHint)
|
|
266
|
+
if not unionArgs:
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
for unionArg in unionArgs:
|
|
270
|
+
if unionArg is type(None):
|
|
271
|
+
continue
|
|
272
|
+
if hasattr(unionArg, "__tupleType__"):
|
|
273
|
+
return unionArg
|
|
274
|
+
|
|
275
|
+
return None
|
|
276
|
+
|
|
259
277
|
@classmethod
|
|
260
278
|
def _checkType(
|
|
261
279
|
cls,
|
|
@@ -284,6 +302,9 @@ class TupleRestfulConverter:
|
|
|
284
302
|
if hasattr(typeHint, "__tupleType__"):
|
|
285
303
|
return None
|
|
286
304
|
|
|
305
|
+
if cls._nestedTupleTypeFromHint(typeHint) is not None:
|
|
306
|
+
return None
|
|
307
|
+
|
|
287
308
|
if type(value) in get_args(typeHint):
|
|
288
309
|
if validator:
|
|
289
310
|
try:
|
|
@@ -425,6 +446,16 @@ class TupleRestfulConverter:
|
|
|
425
446
|
cls._prefixValidationErrors(child.errors, field_path),
|
|
426
447
|
)
|
|
427
448
|
|
|
449
|
+
nestedTupleType = cls._nestedTupleTypeFromHint(typeHint)
|
|
450
|
+
if nestedTupleType is not None and nestedTupleType is not typeHint:
|
|
451
|
+
child = cls.restfulJsonDictToTupleWithValidationResult(
|
|
452
|
+
value, nestedTupleType
|
|
453
|
+
)
|
|
454
|
+
return _ConvertResult(
|
|
455
|
+
child.tuple_,
|
|
456
|
+
cls._prefixValidationErrors(child.errors, field_path),
|
|
457
|
+
)
|
|
458
|
+
|
|
428
459
|
if not get_args(typeHint):
|
|
429
460
|
return _ConvertResult(
|
|
430
461
|
_UNSET,
|
|
@@ -75,7 +75,7 @@ class _VortexConnectionRateLimit:
|
|
|
75
75
|
def __init__(self):
|
|
76
76
|
self._connections: list[_ConnectionDateSuccess] = []
|
|
77
77
|
self._peerConnectionLimitPerIp = None
|
|
78
|
-
self._newConnectionsPerWindow =
|
|
78
|
+
self._newConnectionsPerWindow = 20
|
|
79
79
|
self._rollingNewConnectionWindowSeconds = 10.0
|
|
80
80
|
|
|
81
81
|
def _hasHitPeerConnectionLimit(
|
|
@@ -43,7 +43,7 @@ VortexServer
|
|
|
43
43
|
"""
|
|
44
44
|
|
|
45
45
|
HEART_BEAT_PERIOD = 10.0
|
|
46
|
-
HEART_BEAT_TIMEOUT =
|
|
46
|
+
HEART_BEAT_TIMEOUT = 60.0
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class VortexServer(VortexABC):
|
|
@@ -153,13 +153,15 @@ class VortexServer(VortexABC):
|
|
|
153
153
|
lambda: self._sessionExpired(httpSession.uid)
|
|
154
154
|
)
|
|
155
155
|
|
|
156
|
-
# Update the connection dict in the sessions object
|
|
157
156
|
httpSessionConns = VortexSessionI(httpSession).connections
|
|
157
|
+
for oldConn in list(httpSessionConns.values()):
|
|
158
|
+
if oldConn is not vortexConnection:
|
|
159
|
+
oldConn.close()
|
|
158
160
|
httpSessionConns[vortexUuid] = vortexConnection
|
|
159
161
|
|
|
160
|
-
# Get the old connection if it exists
|
|
161
162
|
if vortexUuid in self._connectionByVortexUuid:
|
|
162
|
-
self._connectionByVortexUuid[vortexUuid]
|
|
163
|
+
if self._connectionByVortexUuid[vortexUuid] is not vortexConnection:
|
|
164
|
+
self._connectionByVortexUuid[vortexUuid].close()
|
|
163
165
|
|
|
164
166
|
# Update the _connectionsByvortexUuid
|
|
165
167
|
self._connectionByVortexUuid[vortexUuid] = vortexConnection
|
|
@@ -267,13 +267,6 @@ class VortexWebSocketUpgradeResource(resource.Resource):
|
|
|
267
267
|
return b"upgrade" in connection and upgrade == b"websocket"
|
|
268
268
|
|
|
269
269
|
def _renderGet(self, request):
|
|
270
|
-
from vortex.VortexFactory import VortexFactory
|
|
271
|
-
|
|
272
|
-
if not VortexFactory.canConnect(str(request.client.host)):
|
|
273
|
-
request.setResponseCode(503)
|
|
274
|
-
request.setHeader("Retry-After", str(max(10, int(random() * 100))))
|
|
275
|
-
return b"Rejected due to new connections throttling."
|
|
276
|
-
|
|
277
270
|
request.setResponseCode(200)
|
|
278
271
|
request.setHeader(b"Content-Type", b"application/json")
|
|
279
272
|
request.setHeader(b"Cache-Control", b"no-store")
|
|
@@ -38,7 +38,7 @@ class JsonSchemaNodeTuple(Tuple):
|
|
|
38
38
|
``tupleToRestfulJsonDict()`` when serialising as a normal Vortex tuple.
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
__tupleType__ = "
|
|
41
|
+
__tupleType__ = "vortex.JsonSchemaNodeTuple"
|
|
42
42
|
|
|
43
43
|
schemaUri: str | None = TupleField(None, typingType=str | None)
|
|
44
44
|
schemaType: str | None = TupleField(None, typingType=str | None)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|