streamlit-octostar-utils 0.5.0.dev5__tar.gz → 0.5.0.dev6__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.
Files changed (45) hide show
  1. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/PKG-INFO +1 -1
  2. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/pyproject.toml +1 -1
  3. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/nifi.py +58 -27
  4. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/LICENSE +0 -0
  5. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/README.md +0 -0
  6. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/__init__.py +0 -0
  7. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
  8. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/celery.py +0 -0
  9. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/contents.py +0 -0
  10. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
  11. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
  12. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
  13. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/combine_fields.py +0 -0
  14. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/entities_parser.py +0 -0
  15. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
  16. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
  17. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py +0 -0
  18. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
  19. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
  20. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
  21. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
  22. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/__init__.py +0 -0
  23. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/dict.py +0 -0
  24. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/filetypes.py +0 -0
  25. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
  26. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
  27. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/timestamp.py +0 -0
  28. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/__init__.py +0 -0
  29. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
  30. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/language.py +0 -0
  31. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/ner.py +0 -0
  32. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/__init__.py +0 -0
  33. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/client.py +0 -0
  34. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/context.py +0 -0
  35. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/permissions.py +0 -0
  36. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/__init__.py +0 -0
  37. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/inheritance.py +0 -0
  38. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/relationships.py +0 -0
  39. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/validation.py +0 -0
  40. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/style/__init__.py +0 -0
  41. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/style/common.py +0 -0
  42. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/__init__.py +0 -0
  43. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
  44. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
  45. {streamlit_octostar_utils-0.5.0.dev5 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/session_state_hot_swapper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit-octostar-utils
3
- Version: 0.5.0.dev5
3
+ Version: 0.5.0.dev6
4
4
  Summary:
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -5,7 +5,7 @@ include = '\.pyi?$'
5
5
 
6
6
  [tool.poetry]
7
7
  name = "streamlit-octostar-utils"
8
- version = "0.5.0-dev.5"
8
+ version = "0.5.0-dev.6"
9
9
  description = ""
10
10
  license = "MIT"
11
11
  authors = ["Octostar"]
@@ -519,7 +519,7 @@ class NifiContextManager(object):
519
519
  )
520
520
  entities = sorted(
521
521
  entities,
522
- key=lambda x: string_to_datetime(x.record.get("os_last_updated_at")),
522
+ key=lambda x: string_to_datetime(x.request.get("entity_timestamp")),
523
523
  )
524
524
  entities = list({e.record["entity_id"]: e for e in entities}.values())
525
525
  entities = [
@@ -592,7 +592,7 @@ class NifiContextManager(object):
592
592
  all_entities.extend(_process_entity(entity, processor_name))
593
593
  all_entities = sorted(
594
594
  all_entities,
595
- key=lambda x: string_to_datetime(x.record.get("os_last_updated_at")),
595
+ key=lambda x: string_to_datetime(x.request.get("entity_timestamp")),
596
596
  )
597
597
  self.out_entities = list({e.record["entity_id"]: e for e in all_entities}.values())
598
598
  self.sync_entities()
@@ -616,34 +616,68 @@ class NifiContextManager(object):
616
616
  @contextmanager
617
617
  def reindex_lock(self, entities: List[Union[dict, "NifiEntity"]], timeout: int = 7200):
618
618
  if not entities:
619
- yield
619
+ yield True
620
620
  return
621
- entities = [e if isinstance(e, dict) else e.record for e in entities]
621
+
622
+ import logging
623
+ _lock_logger = logging.getLogger(__name__)
624
+
625
+ records = []
626
+ for e in entities:
627
+ if isinstance(e, dict):
628
+ records.append(
629
+ (e, e.get("entity_timestamp"))
630
+ )
631
+ else:
632
+ records.append(
633
+ (e.record, e.request.get("entity_timestamp") if e.request else None)
634
+ )
635
+
622
636
  long_expiry = (datetime.now(timezone.utc) + timedelta(seconds=timeout)).strftime("%Y-%m-%dT%H:%M:%SZ")
623
637
  statuses = [
624
638
  {
625
- "entity_id": e["os_entity_uid"],
626
- "entity_type": e["os_concept"],
639
+ "entity_id": rec["os_entity_uid"],
640
+ "entity_type": rec["os_concept"],
641
+ "do_not_update_before": ts,
627
642
  "do_not_reindex_before": long_expiry,
628
- "do_not_update_before": long_expiry,
629
643
  }
630
- for e in entities
644
+ for rec, ts in records
645
+ if ts is not None
631
646
  ]
632
- update_processing_status.sync(statuses, client=self.client)
647
+ if len(statuses) < len(records):
648
+ missing = [rec["os_entity_uid"] for rec, ts in records if ts is None]
649
+ _lock_logger.warning(
650
+ f"reindex_lock: {len(missing)} entities have no entity_timestamp, cannot set lock: {missing}"
651
+ )
652
+ if not statuses:
653
+ yield True
654
+ return
655
+
656
+ result = update_processing_status.sync(statuses, client=self.client)
657
+ skipped_ids = result.get("skipped_entity_ids", []) if isinstance(result, dict) else []
658
+ if skipped_ids:
659
+ _lock_logger.warning(
660
+ f"reindex_lock: {len(skipped_ids)} entities have a newer pipeline run, aborting sync: {skipped_ids}"
661
+ )
662
+ yield False
663
+ return
664
+
633
665
  try:
634
- yield
666
+ yield True
635
667
  finally:
636
668
  short_expiry = (datetime.now(timezone.utc) + timedelta(seconds=1)).strftime("%Y-%m-%dT%H:%M:%SZ")
637
669
  statuses = [
638
670
  {
639
- "entity_id": e["os_entity_uid"],
640
- "entity_type": e["os_concept"],
671
+ "entity_id": rec["os_entity_uid"],
672
+ "entity_type": rec["os_concept"],
673
+ "do_not_update_before": ts,
641
674
  "do_not_reindex_before": short_expiry,
642
- "do_not_update_before": short_expiry,
643
675
  }
644
- for e in entities
676
+ for rec, ts in records
677
+ if ts is not None
645
678
  ]
646
- update_processing_status.sync(statuses, client=self.client)
679
+ if statuses:
680
+ update_processing_status.sync(statuses, client=self.client)
647
681
 
648
682
  def sync_entities(self):
649
683
  if not self.lazy_sync:
@@ -658,14 +692,17 @@ class NifiContextManager(object):
658
692
  fetch_rel_entities, fetch_concept_rels = self._find_relationships_to_fetch(entities)
659
693
 
660
694
  all_entities_to_modify = attachables_to_write + [e[0] for e in entities_to_upsert]
661
- with self.reindex_lock(all_entities_to_modify):
695
+ with self.reindex_lock(all_entities_to_modify) as locked:
696
+ if not locked:
697
+ return
662
698
  self._sync_write_attachables(attachables_to_write)
663
699
  self._sync_upsert_entities(entities_to_upsert)
664
700
  self._sync_fetch_relationships(entities, fetch_rel_entities, fetch_concept_rels)
665
701
 
702
+ now_ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
666
703
  for entity in all_entities_to_modify:
667
704
  entity.request["is_temporary"] = False
668
- entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
705
+ entity.request["entity_timestamp"] = now_ts
669
706
 
670
707
  for entity in entities:
671
708
  entity.sync_params = {}
@@ -712,7 +749,7 @@ class NifiContextManager(object):
712
749
  file.record["entity_id"] = file.record["os_entity_uid"]
713
750
  file.record["entity_type"] = file.record["os_concept"]
714
751
  file.record["entity_label"] = file.label
715
- file.request["entity_timestamp"] = file.record["os_last_updated_at"]
752
+ file.request["entity_timestamp"] = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
716
753
  file.request["is_temporary"] = False
717
754
 
718
755
  def _sync_upsert_entities(self, entities_to_upsert):
@@ -736,7 +773,7 @@ class NifiContextManager(object):
736
773
  entity.record["entity_id"] = entity.record["os_entity_uid"]
737
774
  entity.record["entity_type"] = entity.record["os_concept"]
738
775
  entity.record["entity_label"] = entity.label
739
- entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
776
+ entity.request["entity_timestamp"] = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
740
777
  entity.request["is_temporary"] = False
741
778
 
742
779
  def _find_relationships_to_fetch(self, entities) -> dict:
@@ -1111,7 +1148,7 @@ class NifiEntity(object):
1111
1148
  proxy_otm_children = [c.record for c in proxy_otm_children]
1112
1149
  full_entity_children = sorted(
1113
1150
  full_entity_children,
1114
- key=lambda x: string_to_datetime(x.record.get("os_last_updated_at")),
1151
+ key=lambda x: string_to_datetime(x.request.get("entity_timestamp")),
1115
1152
  )
1116
1153
  full_entity_children = list({c.uid: c.to_json() for c in full_entity_children}.values())
1117
1154
  children = full_entity_children + proxy_entity_children + proxy_otm_children
@@ -1144,7 +1181,7 @@ class NifiEntity(object):
1144
1181
  "relationships": ont_relationships,
1145
1182
  "label_keys": ont_label_keys,
1146
1183
  },
1147
- "entity_timestamp": None,
1184
+ "entity_timestamp": self.request.get("entity_timestamp"),
1148
1185
  "sync_params": {
1149
1186
  NifiContextManager.SyncFlag.UPSERT_ENTITY_ALL.name: True,
1150
1187
  },
@@ -1445,12 +1482,6 @@ class NifiEntity(object):
1445
1482
  to_entity.annotations = recursive_update_dict(to_entity.annotations, annotations_to_propagate, merge_method)
1446
1483
 
1447
1484
 
1448
- def more_recent_than(record_a, record_b):
1449
- return string_to_datetime(record_a.get("os_last_updated_at")) >= string_to_datetime(
1450
- record_b.get("os_last_updated_at")
1451
- )
1452
-
1453
-
1454
1485
  class NifiRoute(Route):
1455
1486
  def __init__(self, app, tasks_routes, processor_name, celery_executor, router=None):
1456
1487
  self.app = app