streamlit-octostar-utils 0.5.0.dev4__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.dev4 → streamlit_octostar_utils-0.5.0.dev6}/PKG-INFO +1 -1
  2. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/pyproject.toml +1 -1
  3. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/nifi.py +60 -28
  4. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/LICENSE +0 -0
  5. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/README.md +0 -0
  6. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/__init__.py +0 -0
  7. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
  8. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/celery.py +0 -0
  9. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/contents.py +0 -0
  10. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
  11. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
  12. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
  13. {streamlit_octostar_utils-0.5.0.dev4 → 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.dev4 → 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.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
  16. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
  17. {streamlit_octostar_utils-0.5.0.dev4 → 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.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
  19. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
  20. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
  21. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
  22. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/__init__.py +0 -0
  23. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/dict.py +0 -0
  24. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/filetypes.py +0 -0
  25. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
  26. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
  27. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/core/timestamp.py +0 -0
  28. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/__init__.py +0 -0
  29. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
  30. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/language.py +0 -0
  31. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/nlp/ner.py +0 -0
  32. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/__init__.py +0 -0
  33. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/client.py +0 -0
  34. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/context.py +0 -0
  35. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/octostar/permissions.py +0 -0
  36. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/__init__.py +0 -0
  37. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/inheritance.py +0 -0
  38. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/relationships.py +0 -0
  39. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/ontology/validation.py +0 -0
  40. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/style/__init__.py +0 -0
  41. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/style/common.py +0 -0
  42. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/__init__.py +0 -0
  43. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
  44. {streamlit_octostar_utils-0.5.0.dev4 → streamlit_octostar_utils-0.5.0.dev6}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
  45. {streamlit_octostar_utils-0.5.0.dev4 → 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.dev4
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.4"
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,32 +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"],
627
- "do_not_reindex_at": long_expiry,
639
+ "entity_id": rec["os_entity_uid"],
640
+ "entity_type": rec["os_concept"],
641
+ "do_not_update_before": ts,
642
+ "do_not_reindex_before": long_expiry,
628
643
  }
629
- for e in entities
644
+ for rec, ts in records
645
+ if ts is not None
630
646
  ]
631
- 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
+
632
665
  try:
633
- yield
666
+ yield True
634
667
  finally:
635
668
  short_expiry = (datetime.now(timezone.utc) + timedelta(seconds=1)).strftime("%Y-%m-%dT%H:%M:%SZ")
636
669
  statuses = [
637
670
  {
638
- "entity_id": e["os_entity_uid"],
639
- "entity_type": e["os_concept"],
640
- "do_not_reindex_at": short_expiry,
671
+ "entity_id": rec["os_entity_uid"],
672
+ "entity_type": rec["os_concept"],
673
+ "do_not_update_before": ts,
674
+ "do_not_reindex_before": short_expiry,
641
675
  }
642
- for e in entities
676
+ for rec, ts in records
677
+ if ts is not None
643
678
  ]
644
- update_processing_status.sync(statuses, client=self.client)
679
+ if statuses:
680
+ update_processing_status.sync(statuses, client=self.client)
645
681
 
646
682
  def sync_entities(self):
647
683
  if not self.lazy_sync:
@@ -656,14 +692,17 @@ class NifiContextManager(object):
656
692
  fetch_rel_entities, fetch_concept_rels = self._find_relationships_to_fetch(entities)
657
693
 
658
694
  all_entities_to_modify = attachables_to_write + [e[0] for e in entities_to_upsert]
659
- 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
660
698
  self._sync_write_attachables(attachables_to_write)
661
699
  self._sync_upsert_entities(entities_to_upsert)
662
700
  self._sync_fetch_relationships(entities, fetch_rel_entities, fetch_concept_rels)
663
701
 
702
+ now_ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
664
703
  for entity in all_entities_to_modify:
665
704
  entity.request["is_temporary"] = False
666
- entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
705
+ entity.request["entity_timestamp"] = now_ts
667
706
 
668
707
  for entity in entities:
669
708
  entity.sync_params = {}
@@ -710,7 +749,7 @@ class NifiContextManager(object):
710
749
  file.record["entity_id"] = file.record["os_entity_uid"]
711
750
  file.record["entity_type"] = file.record["os_concept"]
712
751
  file.record["entity_label"] = file.label
713
- 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")
714
753
  file.request["is_temporary"] = False
715
754
 
716
755
  def _sync_upsert_entities(self, entities_to_upsert):
@@ -722,7 +761,6 @@ class NifiContextManager(object):
722
761
  {
723
762
  "entity_type": entity.record["os_concept"],
724
763
  "os_entity_uid": entity.record["os_entity_uid"],
725
- "os_last_updated_at": entity.request["entity_timestamp"],
726
764
  "fields": {k: entity.record.get(k) for k in fields},
727
765
  }
728
766
  for entity, fields in entities_to_upsert
@@ -735,7 +773,7 @@ class NifiContextManager(object):
735
773
  entity.record["entity_id"] = entity.record["os_entity_uid"]
736
774
  entity.record["entity_type"] = entity.record["os_concept"]
737
775
  entity.record["entity_label"] = entity.label
738
- 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")
739
777
  entity.request["is_temporary"] = False
740
778
 
741
779
  def _find_relationships_to_fetch(self, entities) -> dict:
@@ -1110,7 +1148,7 @@ class NifiEntity(object):
1110
1148
  proxy_otm_children = [c.record for c in proxy_otm_children]
1111
1149
  full_entity_children = sorted(
1112
1150
  full_entity_children,
1113
- 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")),
1114
1152
  )
1115
1153
  full_entity_children = list({c.uid: c.to_json() for c in full_entity_children}.values())
1116
1154
  children = full_entity_children + proxy_entity_children + proxy_otm_children
@@ -1143,7 +1181,7 @@ class NifiEntity(object):
1143
1181
  "relationships": ont_relationships,
1144
1182
  "label_keys": ont_label_keys,
1145
1183
  },
1146
- "entity_timestamp": None,
1184
+ "entity_timestamp": self.request.get("entity_timestamp"),
1147
1185
  "sync_params": {
1148
1186
  NifiContextManager.SyncFlag.UPSERT_ENTITY_ALL.name: True,
1149
1187
  },
@@ -1444,12 +1482,6 @@ class NifiEntity(object):
1444
1482
  to_entity.annotations = recursive_update_dict(to_entity.annotations, annotations_to_propagate, merge_method)
1445
1483
 
1446
1484
 
1447
- def more_recent_than(record_a, record_b):
1448
- return string_to_datetime(record_a.get("os_last_updated_at")) >= string_to_datetime(
1449
- record_b.get("os_last_updated_at")
1450
- )
1451
-
1452
-
1453
1485
  class NifiRoute(Route):
1454
1486
  def __init__(self, app, tasks_routes, processor_name, celery_executor, router=None):
1455
1487
  self.app = app