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 CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  __author__ = """Asterio Gonzalez"""
4
4
  __email__ = "asterio.gonzalez@gmail.com"
5
- __version__ = "0.1.313"
5
+ __version__ = "0.1.314"
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
@@ -100,6 +100,8 @@ GEOMETRY_COMP_KEY = "geometry__"
100
100
  GEOJSON_KEY = "geojson"
101
101
  GEOLINK_KEY = "geolink"
102
102
 
103
+ COMPARISON_PATTERNS = "compare__"
104
+
103
105
  GEOSPECS_KEYS = [GEOMETRY_KEY, GEOMETRY_SHAPE_KEY, GEOJSON_KEY]
104
106
 
105
107
  UBICATION_KEY = "ubication"
syncmodels/exceptions.py CHANGED
@@ -23,5 +23,9 @@ class NonRecoverableAuth(NonRecoverable):
23
23
  """
24
24
 
25
25
 
26
+ class BadLogic(NonRecoverable):
27
+ """Bad Logic File"""
28
+
29
+
26
30
  class BadData(SyncModelException):
27
31
  """Data is not properly formatted."""
@@ -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 merge as merge_dict, build_dict, json_compatible
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
- - cteate / update Wave info with original the original query data
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 or []).intersection(data):
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
- # t0 = time.time()
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
- # t1 = time.time()
970
- # _elapsed = t1 - t0
985
+ t1 = time.time()
986
+ _elapsed = t1 - t0
971
987
  existing = identical + similar
972
- N2 = len(existing)
973
- if data_sort_blueprint and N2 > 1:
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
- N2,
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
- N2,
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 exists[key] != data[key]:
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
- exists[key],
1011
- data[key],
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.313
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.313
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=F-gwFoSn9hneX4i5kpR9dYY6CUDVidYhx9nW2WiEJcU,142
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=vfMn39Fev1yKY8ELvTK3rM-RUPiiy8YoxAG2q7b9MkM,94247
3
+ syncmodels/crawler.py,sha256=U6F0QlzmxkReCB6X2Xbxmm2rRn99GEX005dG7AFl8xE,94430
4
4
  syncmodels/crud.py,sha256=viHBwzczcjNyFiLxL7VGYSbWJW5VjU8AvKaPufBMP7M,15303
5
- syncmodels/definitions.py,sha256=2P-Sfgj18viSHZ-wAK4WfQEzDKdyygs8Z-XLzA0jg_k,5420
6
- syncmodels/exceptions.py,sha256=8EOYW8h_2noeoKAYqG4aEQTgB1FEkamxKt3t4pDJ3pM,626
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=N69l-CSZOZomwVJMALKbPI1jPsngxDNlxbxX9SV4vfg,70505
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=W_s_rIWceGni2GMdhlrdZTTxTG-43n2CQDhPgyJfdE0,84711
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.313.dist-info/AUTHORS.rst,sha256=3ZPoqg8Aav8DSYKd0fwcwn4_5HwSiMLart0E5Un00-U,168
306
- syncmodels-0.1.313.dist-info/LICENSE,sha256=uzMOYtIiUsnsD0xHJR7aJWJ4v_bvan0kTnvufy5eNoA,1075
307
- syncmodels-0.1.313.dist-info/METADATA,sha256=NRPuII9unMl4-z_TQqvb9W-Tp94LIT6CXU3ctK_v3us,2700
308
- syncmodels-0.1.313.dist-info/WHEEL,sha256=SrDKpSbFN1G94qcmBqS9nyHcDMp9cUS9OC06hC0G3G0,109
309
- syncmodels-0.1.313.dist-info/entry_points.txt,sha256=dMnigjZsHMxTwXiiZyBZdBbMYE0-hY3L5cG15EcDAzw,51
310
- syncmodels-0.1.313.dist-info/top_level.txt,sha256=2DfQ9NuAhKMjY3BvQGVBA7GfqTm7EoHNbaehSUiqiHQ,11
311
- syncmodels-0.1.313.dist-info/RECORD,,
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,,