syncmodels 0.1.313__py2.py3-none-any.whl → 0.1.314__py2.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.
- syncmodels/__init__.py +1 -1
- syncmodels/crawler.py +6 -2
- syncmodels/definitions.py +2 -0
- syncmodels/exceptions.py +4 -0
- syncmodels/logic/browser.py +5 -3
- syncmodels/storage.py +59 -23
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/METADATA +2 -2
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/RECORD +13 -13
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/AUTHORS.rst +0 -0
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/LICENSE +0 -0
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/WHEEL +0 -0
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/entry_points.txt +0 -0
- {syncmodels-0.1.313.dist-info → syncmodels-0.1.314.dist-info}/top_level.txt +0 -0
syncmodels/__init__.py
CHANGED
syncmodels/crawler.py
CHANGED
@@ -152,7 +152,7 @@ from syncmodels.http import (
|
|
152
152
|
# from syncmodels.registry import iRegistry
|
153
153
|
from syncmodels.auth import iAuthenticator
|
154
154
|
from syncmodels.storage import WaveStorage, Storage
|
155
|
-
from syncmodels.exceptions import NonRecoverable, NonRecoverableAuth, BadData
|
155
|
+
from syncmodels.exceptions import BadLogic, NonRecoverable, NonRecoverableAuth, BadData
|
156
156
|
from syncmodels.syncmodels import SyncModel, COPY
|
157
157
|
from .crud import parse_duri, DEFAULT_DATABASE, DEFAULT_NAMESPACE
|
158
158
|
|
@@ -770,6 +770,10 @@ class iBot(iAgent):
|
|
770
770
|
# abort responsability chain
|
771
771
|
log.error("Inexpected responsability chain abortion")
|
772
772
|
break
|
773
|
+
except (BadLogic,) as why:
|
774
|
+
# separate to have more fine grain control
|
775
|
+
await self.handle_non_recoverable(why, context)
|
776
|
+
|
773
777
|
except Exception as why:
|
774
778
|
log.error(why)
|
775
779
|
log.error("".join(traceback.format_exception(*sys.exc_info())))
|
@@ -1071,7 +1075,7 @@ class iBot(iAgent):
|
|
1071
1075
|
result = await extract_result(response)
|
1072
1076
|
# result = await response.text()
|
1073
1077
|
log.error(
|
1074
|
-
"[%s] server sent: %s",
|
1078
|
+
"Forbidden [%s] server sent: %s",
|
1075
1079
|
response.status,
|
1076
1080
|
result,
|
1077
1081
|
)
|
syncmodels/definitions.py
CHANGED
syncmodels/exceptions.py
CHANGED
syncmodels/logic/browser.py
CHANGED
@@ -45,7 +45,7 @@ from syncmodels.crud import parse_duri
|
|
45
45
|
from ..definitions import TASK_KEY, KIND_KEY, ORG_URL, DURI, ID_KEY, VOL_DATA
|
46
46
|
from ..session import iSession
|
47
47
|
from ..crawler import iBot
|
48
|
-
from ..crawler import MetaExtractPlugin, PutPlugin, SetURIPlugin
|
48
|
+
from ..crawler import MetaExtractPlugin, PutPlugin, SetURIPlugin, SortPlugin
|
49
49
|
|
50
50
|
from .swarm import SwarmBot, SwarmCrawler, SWARM_REGISTER, SWARM_TASKS
|
51
51
|
from .analyzer import XPathAnalyzer
|
@@ -717,13 +717,15 @@ class BrowserLogicBot(SwarmBot):
|
|
717
717
|
)
|
718
718
|
|
719
719
|
def _add_plugins(self):
|
720
|
-
super()._add_plugins()
|
720
|
+
# super()._add_plugins()
|
721
|
+
# self.plugins.clear()
|
721
722
|
|
722
|
-
self.plugins.clear()
|
723
723
|
# self.add_plugin(HashStreamPlugin())
|
724
724
|
self.add_plugin(MetaExtractPlugin(geojson=False))
|
725
725
|
self.add_plugin(PutPlugin())
|
726
726
|
self.add_plugin(SetURIPlugin())
|
727
|
+
# self.add_plugin(SortPlugin())
|
728
|
+
|
727
729
|
# self.add_plugin(RenameKeys())
|
728
730
|
# self.add_plugin(UnwrapResponse())
|
729
731
|
# self.add_plugin(RegExtractor())
|
syncmodels/storage.py
CHANGED
@@ -26,7 +26,13 @@ from surrealist import Surreal as Surrealist
|
|
26
26
|
|
27
27
|
from agptools.logs import logger
|
28
28
|
from agptools.helpers import parse_uri, build_uri, DATE, tf
|
29
|
-
from agptools.containers import
|
29
|
+
from agptools.containers import (
|
30
|
+
merge as merge_dict,
|
31
|
+
build_dict,
|
32
|
+
json_compatible,
|
33
|
+
Walk,
|
34
|
+
CWalk,
|
35
|
+
)
|
30
36
|
|
31
37
|
from syncmodels.definitions import (
|
32
38
|
REVERSE_SORT_KEY,
|
@@ -40,6 +46,13 @@ from syncmodels.http import (
|
|
40
46
|
# USER_AGENT,
|
41
47
|
APPLICATION_JSON,
|
42
48
|
)
|
49
|
+
from syncmodels.exceptions import (
|
50
|
+
SyncModelException,
|
51
|
+
BadLogic,
|
52
|
+
NonRecoverable,
|
53
|
+
NonRecoverableAuth,
|
54
|
+
BadData,
|
55
|
+
)
|
43
56
|
|
44
57
|
from .helpers.importers import JSONVerter
|
45
58
|
|
@@ -72,6 +85,7 @@ from .definitions import (
|
|
72
85
|
SORT_KEY,
|
73
86
|
LIMIT_KEY,
|
74
87
|
WAVE_LAST_KEY,
|
88
|
+
COMPARISON_PATTERNS,
|
75
89
|
)
|
76
90
|
from .crud import (
|
77
91
|
DEFAULT_DATABASE,
|
@@ -120,6 +134,12 @@ UTC_TZ = pytz.timezone("UTC")
|
|
120
134
|
|
121
135
|
|
122
136
|
# REGEXP_FQUI = re.compile(r"((?P<ns>[^/]*?)/)?(?P<table>[^:]+):(?P<uid>.*)$")
|
137
|
+
|
138
|
+
|
139
|
+
def comparable_struct(data, patterns):
|
140
|
+
wdata = Walk(data)
|
141
|
+
|
142
|
+
|
123
143
|
def split_fqui(fqid):
|
124
144
|
"try to split FQUID into table and uid"
|
125
145
|
try:
|
@@ -130,7 +150,7 @@ def split_fqui(fqid):
|
|
130
150
|
|
131
151
|
|
132
152
|
def normalize_payload(data, keys):
|
133
|
-
for key in set(keys).intersection(data):
|
153
|
+
for key in set(keys or []).intersection(data):
|
134
154
|
value = DATE(data[key])
|
135
155
|
if isinstance(value, datetime):
|
136
156
|
if not value.tzinfo:
|
@@ -777,7 +797,7 @@ class WaveStorage(iWaves, iStorage):
|
|
777
797
|
|
778
798
|
2. if the object has been inserted in `tube` then:
|
779
799
|
- create / update Snapshot
|
780
|
-
-
|
800
|
+
- create / update Wave info with original the original query data
|
781
801
|
|
782
802
|
|
783
803
|
e: exists
|
@@ -818,8 +838,8 @@ class WaveStorage(iWaves, iStorage):
|
|
818
838
|
if model := kw.get(MODEL_KEY):
|
819
839
|
self.register_metadata(uri, {"model": model})
|
820
840
|
|
821
|
-
sort_keys = kw.get(SORT_KEY
|
822
|
-
reverse_sort_keys = kw.get(REVERSE_SORT_KEY
|
841
|
+
sort_keys = kw.get(SORT_KEY) or []
|
842
|
+
reverse_sort_keys = kw.get(REVERSE_SORT_KEY) or []
|
823
843
|
sort_kw_presence = all([kw.get(_) for _ in sort_keys])
|
824
844
|
sort_data_presence = all([data.get(_) for _ in reverse_sort_keys])
|
825
845
|
|
@@ -844,7 +864,7 @@ class WaveStorage(iWaves, iStorage):
|
|
844
864
|
# stream = [kw]
|
845
865
|
if not (sort_keys := SortKeyFinder.find_sort_key(stream=stream)):
|
846
866
|
kind = kw.get(KIND_KEY)
|
847
|
-
sort_keys = kw[SORT_KEY] = SortKeyFinder.get(kind)
|
867
|
+
sort_keys = kw[SORT_KEY] = SortKeyFinder.get(kind) or []
|
848
868
|
|
849
869
|
kw[SORT_KEY] = sort_keys
|
850
870
|
log.debug("[%s] found: %s as sort_keys", uri, sort_keys)
|
@@ -871,7 +891,7 @@ class WaveStorage(iWaves, iStorage):
|
|
871
891
|
normalize_payload(data, sort_keys)
|
872
892
|
|
873
893
|
monotonic = data.setdefault(MONOTONIC_KEY, monotonic_wave())
|
874
|
-
for monotonic_key in set(sort_keys
|
894
|
+
for monotonic_key in set(sort_keys).intersection(data):
|
875
895
|
monotonic_value = DATE(data[monotonic_key])
|
876
896
|
|
877
897
|
# seconds
|
@@ -885,7 +905,6 @@ class WaveStorage(iWaves, iStorage):
|
|
885
905
|
since_value = pytz.utc.localize(since_value)
|
886
906
|
since_value = since_value.astimezone(UTC_TZ)
|
887
907
|
since_value = since_value.strftime("%Y-%m-%dT%H:%M:%SZ")
|
888
|
-
|
889
908
|
break
|
890
909
|
else:
|
891
910
|
monotonic_key = MONOTONIC_KEY # ??
|
@@ -921,8 +940,6 @@ class WaveStorage(iWaves, iStorage):
|
|
921
940
|
sort_keys,
|
922
941
|
MASK,
|
923
942
|
)
|
924
|
-
# existing = await self.storage.query(query, **blueprint)
|
925
|
-
# N = len(existing)
|
926
943
|
|
927
944
|
# TODO: agp: cache and get behaviour from database?
|
928
945
|
if not (behavior := self.behavior_uri.get(query)):
|
@@ -938,8 +955,7 @@ class WaveStorage(iWaves, iStorage):
|
|
938
955
|
|
939
956
|
self.behavior_uri[query] = behavior
|
940
957
|
|
941
|
-
|
942
|
-
|
958
|
+
t0 = time.time()
|
943
959
|
# search the same data
|
944
960
|
# TODO: update blueprint
|
945
961
|
blueprint = {
|
@@ -966,49 +982,67 @@ class WaveStorage(iWaves, iStorage):
|
|
966
982
|
**blueprint,
|
967
983
|
# **data_sort_bp,
|
968
984
|
)
|
969
|
-
|
970
|
-
|
985
|
+
t1 = time.time()
|
986
|
+
_elapsed = t1 - t0
|
971
987
|
existing = identical + similar
|
972
|
-
|
973
|
-
|
988
|
+
N = len(existing)
|
989
|
+
log.debug(
|
990
|
+
"[%s] found [%s] similar records in %s secs",
|
991
|
+
blueprint,
|
992
|
+
N,
|
993
|
+
_elapsed,
|
994
|
+
)
|
995
|
+
if data_sort_blueprint and N > 1:
|
974
996
|
if behavior & ALLOW_DUPLICATED_ITEMS:
|
975
997
|
log.debug(
|
976
998
|
"tube [%s] has multiples records: [%s] records, but ALLOW_SAME_DATE_DIFFERENT_VALUES is defined",
|
977
999
|
uid,
|
978
|
-
|
1000
|
+
N,
|
979
1001
|
)
|
980
1002
|
existing.clear()
|
981
1003
|
else:
|
982
1004
|
log.debug(
|
983
1005
|
"tube has multiples records: [%s] = %s records, must just 1 and sort_key is defined by: [%s]",
|
984
1006
|
uid,
|
985
|
-
|
1007
|
+
N,
|
986
1008
|
data_sort_blueprint,
|
987
1009
|
)
|
988
1010
|
|
989
1011
|
push = True
|
1012
|
+
patterns = kw.get(COMPARISON_PATTERNS)
|
1013
|
+
if patterns:
|
1014
|
+
wdata = CWalk(data, include=patterns, exclude=MASK)
|
1015
|
+
if not wdata:
|
1016
|
+
log.warning("patterns don't get any data")
|
1017
|
+
raise BadLogic(data)
|
1018
|
+
else:
|
1019
|
+
patterns = [r".*"]
|
1020
|
+
wdata = CWalk(data, include=patterns, exclude=MASK)
|
990
1021
|
for exists in existing:
|
1022
|
+
wexists = CWalk(exists, include=patterns, exclude=MASK)
|
991
1023
|
existing_sort_blueprint = build_dict(exists, reverse_sort_keys)
|
992
1024
|
# existing_sort_blueprint = build_comparisson_dict(exists, reverse_sort_keys)
|
993
1025
|
|
994
1026
|
same_sort_key = existing_sort_blueprint == data_sort_blueprint
|
995
1027
|
|
996
1028
|
# check if we must "duplicate" data inside tube
|
997
|
-
keys0 = set(exists).difference(MASK)
|
998
|
-
keys1 = set(data).difference(MASK)
|
1029
|
+
# keys0 = set(exists).difference(MASK)
|
1030
|
+
# keys1 = set(data).difference(MASK)
|
1031
|
+
keys0 = set(wexists)
|
1032
|
+
keys1 = set(wdata)
|
999
1033
|
same_structure = keys0 == keys1
|
1000
1034
|
|
1001
1035
|
same_values = False
|
1002
1036
|
if same_sort_key and same_structure:
|
1003
1037
|
for key in keys0:
|
1004
|
-
if
|
1038
|
+
if wexists[key] != wdata[key]:
|
1005
1039
|
log.debug(
|
1006
1040
|
"[%s].[%s].[%s]: %s != %s",
|
1007
1041
|
uid,
|
1008
1042
|
data_sort_blueprint,
|
1009
1043
|
key,
|
1010
|
-
|
1011
|
-
|
1044
|
+
wexists[key],
|
1045
|
+
wdata[key],
|
1012
1046
|
)
|
1013
1047
|
break
|
1014
1048
|
else:
|
@@ -1235,6 +1269,8 @@ class WaveStorage(iWaves, iStorage):
|
|
1235
1269
|
return all([res0, res1, res2])
|
1236
1270
|
else:
|
1237
1271
|
return True
|
1272
|
+
except SyncModelException as why:
|
1273
|
+
raise why
|
1238
1274
|
except Exception as why: # pragma: nocover
|
1239
1275
|
log.error(why)
|
1240
1276
|
log.error("".join(traceback.format_exception(*sys.exc_info())))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: syncmodels
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.314
|
4
4
|
Summary: Synchronizable Models
|
5
5
|
Home-page: https://github.com/asterio.gonzalez/syncmodels
|
6
6
|
Author: Asterio Gonzalez
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Requires-Python: >=3.6
|
19
19
|
License-File: LICENSE
|
20
20
|
License-File: AUTHORS.rst
|
21
|
-
Requires-Dist: agptools>=0.1.
|
21
|
+
Requires-Dist: agptools>=0.1.314
|
22
22
|
Requires-Dist: aiocache
|
23
23
|
Requires-Dist: aiohttp
|
24
24
|
Requires-Dist: Click
|
@@ -1,9 +1,9 @@
|
|
1
|
-
syncmodels/__init__.py,sha256=
|
1
|
+
syncmodels/__init__.py,sha256=G_3tlPvmtf1CQaauaKV6PoulB_iHJ43bVbH_1q_p8aI,142
|
2
2
|
syncmodels/context.py,sha256=k1Gs_ip9BfyRFpyRnzqYvRDKo0sYBqJsh6z9sWln9oE,451
|
3
|
-
syncmodels/crawler.py,sha256=
|
3
|
+
syncmodels/crawler.py,sha256=U6F0QlzmxkReCB6X2Xbxmm2rRn99GEX005dG7AFl8xE,94430
|
4
4
|
syncmodels/crud.py,sha256=viHBwzczcjNyFiLxL7VGYSbWJW5VjU8AvKaPufBMP7M,15303
|
5
|
-
syncmodels/definitions.py,sha256=
|
6
|
-
syncmodels/exceptions.py,sha256=
|
5
|
+
syncmodels/definitions.py,sha256=dTMxcwcIeYQthZCZXNQmaO1SolWY-WhafASyl91xTo0,5455
|
6
|
+
syncmodels/exceptions.py,sha256=ZLAwu19cs2UN2Sv3jaLnixT_jRI7T42TfyutCkUsuIk,685
|
7
7
|
syncmodels/geofactory.py,sha256=1FkrdEn0QA0O4_lSUAwjqXH2dmlQWi32AkntnG4AEQY,10372
|
8
8
|
syncmodels/http.py,sha256=FFVT3QJJgur2dv1Q_7l9ZsWN8z6_gUjOT9hJff1ZAqk,3335
|
9
9
|
syncmodels/parallel.py,sha256=Ll8HmyFF9v9fIofqqSgfhyTlklvb77mTtNdG5Y9lqdQ,7145
|
@@ -11,7 +11,7 @@ syncmodels/registry.py,sha256=YaQtgbSwa0je1MpCcVHALI3_b85vrddyOlhsnrUcKZs,8224
|
|
11
11
|
syncmodels/requests.py,sha256=wWoC5hPDm1iBM_zrlyKRauzhXgdKR3pT5RqyC-5UZhQ,538
|
12
12
|
syncmodels/runner.py,sha256=IHDKuQ3yJ1DN9wktMiIrerPepYX61tc3AzbFfuUqEFw,5454
|
13
13
|
syncmodels/schema.py,sha256=uinUt8Asq_x7xa6MKWVXNyoWO6gKocjGPppjimaXzEU,2492
|
14
|
-
syncmodels/storage.py,sha256
|
14
|
+
syncmodels/storage.py,sha256=-kdXuPjkHBPauoXTWcmwK4jmH9hr2X1JFERqluznL1Q,71513
|
15
15
|
syncmodels/syncmodels.py,sha256=EzSC4C75V4wJDmsLLbp8YUVwqA6A16KCNW8nB-MqPcs,10567
|
16
16
|
syncmodels/timequeue.py,sha256=YRd3ULRaIhoszaBsYhfr0epMqAbL6-NwVEtScjUYttM,595
|
17
17
|
syncmodels/wave.py,sha256=Gra22BLiA9z2nF-6diXpjAc4GZv9nebmyvHxdAfXec4,7764
|
@@ -38,7 +38,7 @@ syncmodels/helpers/units.py,sha256=g50m5DQrAyP_qpDRa4LCEA5Rz2UZUmlIixfWG_ddw9I,3
|
|
38
38
|
syncmodels/logic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
syncmodels/logic/activity_logger.py,sha256=8wjvgRwaNbibYWGgl-trovSS70yNkoCTlb-AIx3aZEE,14053
|
40
40
|
syncmodels/logic/analyzer.py,sha256=7JDIvZIiDVgdABaaRk7TEbzOFM6HAH3RaSsIDmL4QVE,12291
|
41
|
-
syncmodels/logic/browser.py,sha256=
|
41
|
+
syncmodels/logic/browser.py,sha256=KqvOLPAl2p5EBol7FK-XYvOXeDnu0h9Dz7xfagKTheM,84768
|
42
42
|
syncmodels/logic/swarm.py,sha256=eRBVlNAOzzWKFGCb7LGLx2aj7yQlTY1OwLoeSEllvXY,17207
|
43
43
|
syncmodels/mapper/__init__.py,sha256=jS82LFr9zzyqXBz82tSw04vDowhTpKxhg_W2XvhUlt0,129
|
44
44
|
syncmodels/mapper/fiware.py,sha256=auszPmhCS46z_68MXjksrQAFUfctjbVrVdBvOpOkMj8,523
|
@@ -302,10 +302,10 @@ syncmodels/session/postgresql.py,sha256=ZMIu1Rv93pKfvFlovFBmWArzlrT2xaQWNYGZT_LW
|
|
302
302
|
syncmodels/session/sql.py,sha256=bD7zXRrEKKJmqY2UoibWENuWb5zHrrU72F3_dYbS6LY,6569
|
303
303
|
syncmodels/session/sqlite.py,sha256=nCDjopLiBpX1F10qkKoARM7JrVdIpJ1WdGOduFVxaiA,2080
|
304
304
|
syncmodels/source/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
305
|
-
syncmodels-0.1.
|
306
|
-
syncmodels-0.1.
|
307
|
-
syncmodels-0.1.
|
308
|
-
syncmodels-0.1.
|
309
|
-
syncmodels-0.1.
|
310
|
-
syncmodels-0.1.
|
311
|
-
syncmodels-0.1.
|
305
|
+
syncmodels-0.1.314.dist-info/AUTHORS.rst,sha256=3ZPoqg8Aav8DSYKd0fwcwn4_5HwSiMLart0E5Un00-U,168
|
306
|
+
syncmodels-0.1.314.dist-info/LICENSE,sha256=uzMOYtIiUsnsD0xHJR7aJWJ4v_bvan0kTnvufy5eNoA,1075
|
307
|
+
syncmodels-0.1.314.dist-info/METADATA,sha256=59uo0tcMb8sXzIoBOlGNPUdyivZA7wIhkYj1hXZ1sMU,2700
|
308
|
+
syncmodels-0.1.314.dist-info/WHEEL,sha256=SrDKpSbFN1G94qcmBqS9nyHcDMp9cUS9OC06hC0G3G0,109
|
309
|
+
syncmodels-0.1.314.dist-info/entry_points.txt,sha256=dMnigjZsHMxTwXiiZyBZdBbMYE0-hY3L5cG15EcDAzw,51
|
310
|
+
syncmodels-0.1.314.dist-info/top_level.txt,sha256=2DfQ9NuAhKMjY3BvQGVBA7GfqTm7EoHNbaehSUiqiHQ,11
|
311
|
+
syncmodels-0.1.314.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|