streamlit-octostar-utils 0.4.2.dev5__tar.gz → 0.4.2.dev7__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.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/PKG-INFO +1 -1
  2. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/pyproject.toml +1 -1
  3. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/nifi.py +120 -183
  4. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/ontology/inheritance.py +12 -0
  5. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/LICENSE +0 -0
  6. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/README.md +0 -0
  7. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/__init__.py +0 -0
  8. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
  9. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/celery.py +0 -0
  10. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/contents.py +0 -0
  11. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
  12. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
  13. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
  14. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/combine_fields.py +0 -0
  15. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/entities_parser.py +0 -0
  16. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
  17. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
  18. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py +0 -0
  19. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
  20. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
  21. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
  22. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
  23. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/__init__.py +0 -0
  24. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/dict.py +0 -0
  25. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/filetypes.py +0 -0
  26. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
  27. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
  28. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/core/timestamp.py +0 -0
  29. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/nlp/__init__.py +0 -0
  30. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
  31. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/nlp/language.py +0 -0
  32. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/nlp/ner.py +0 -0
  33. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/octostar/__init__.py +0 -0
  34. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/octostar/client.py +0 -0
  35. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/octostar/context.py +0 -0
  36. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/octostar/permissions.py +0 -0
  37. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/ontology/__init__.py +0 -0
  38. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/ontology/relationships.py +0 -0
  39. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/ontology/validation.py +0 -0
  40. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/style/__init__.py +0 -0
  41. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/style/common.py +0 -0
  42. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/threading/__init__.py +0 -0
  43. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
  44. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
  45. {streamlit_octostar_utils-0.4.2.dev5 → streamlit_octostar_utils-0.4.2.dev7}/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.4.2.dev5
3
+ Version: 0.4.2.dev7
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.4.2-dev.5"
8
+ version = "0.4.2-dev.7"
9
9
  description = ""
10
10
  license = "MIT"
11
11
  authors = ["Octostar"]
@@ -14,17 +14,18 @@ from fastapi import Request
14
14
  from fastapi.responses import JSONResponse
15
15
  from starlette.exceptions import HTTPException as StarletteHTTPException
16
16
 
17
- from octostar.utils.workspace import upsert_entities, write_file
17
+ from octostar.utils.workspace import upsert_entities
18
18
  from octostar.utils.ontology import fetch_ontology_data
19
19
  from octostar.utils.workspace.permissions import get_permissions, PermissionLevel
20
- from octostar.client import make_client
21
20
  from octostar.utils.pipeline import update_processing_status
21
+ from octostar.utils.workspace import write_attachment
22
+ from octostar.client import make_client
22
23
 
23
24
  from ..core.dict import recursive_update_dict, travel_dict, jsondict_hash
24
25
  from ..core.timestamp import now, string_to_datetime
25
26
  from .fastapi import DefaultErrorRoute, Route
26
- from ..ontology.inheritance import is_child_concept as is_child_concept_fn, get_label_keys
27
- from .contents import Contents, WorkspaceAttachmentContents, TemporaryAttachmentContents, ContentsLocation
27
+ from ..ontology.inheritance import is_child_concept as is_child_concept_fn, get_label, get_label_keys
28
+ from .contents import Contents, WorkspaceAttachmentContents, TemporaryAttachmentContents
28
29
 
29
30
 
30
31
  class RelationshipName(BaseModel):
@@ -43,7 +44,11 @@ TAG_RELATIONSHIP = RelationshipName(name="has_tag", type="mtm")
43
44
  FRAGMENT_RELATIONSHIP = RelationshipName(name="is_fragment_of", type="otm")
44
45
  PREVIOUS_FRAGMENT_RELATIONSHIP = RelationshipName(name="has_previous_fragment", type="otm")
45
46
  NEXT_FRAGMENT_RELATIONSHIP = RelationshipName(name="has_next_fragment", type="otm")
46
-
47
+ OS_RESERVED_FIELDS = [
48
+ "os_entity_uid", "entity_id", "entity_type", "os_concept",
49
+ "entity_label", "os_created_at", "os_created_by",
50
+ "os_last_updated_at", "os_last_updated_by",
51
+ ]
47
52
 
48
53
  class NifiProxyEntityModel(BaseModel):
49
54
  entity_id: str
@@ -73,7 +78,6 @@ class NifiEntityModel(BaseModel):
73
78
  nifi_attributes: dict = Field(default_factory=dict)
74
79
  config: dict = Field(default_factory=dict)
75
80
  metrics: dict = Field(default_factory=dict)
76
- contents_pointer: Optional[dict] = None
77
81
  is_temporary: bool = False
78
82
  exception: dict = Field(default_factory=dict)
79
83
  last_processor_name: Optional[str] = None
@@ -429,35 +433,86 @@ class NifiContextManager(object):
429
433
  entities = [e for e in self.out_entities if e.record["entity_id"] in self.nonlazy_sync_ids]
430
434
  if not entities:
431
435
  return
432
- reserved_fields = [
433
- "os_entity_uid",
434
- "entity_id",
435
- "entity_type",
436
- "os_concept",
437
- "entity_label",
438
- "os_created_at",
439
- "os_created_by",
440
- "os_last_updated_at",
441
- "os_last_updated_by",
442
- ]
443
- entities_to_upsert = []
444
- files_to_write = []
436
+
437
+ attachables_to_write = self._find_attachables_to_write(entities)
438
+ entities_to_upsert = self._find_entities_to_upsert(entities)
439
+ fetch_rel_entities, fetch_concept_rels = self._find_relationships_to_fetch(entities)
440
+
441
+ all_entities_to_modify = attachables_to_write + [e[0] for e in entities_to_upsert]
442
+ with self.reindex_lock(all_entities_to_modify):
443
+ self._sync_write_attachables(attachables_to_write)
444
+ self._sync_upsert_entities(entities_to_upsert)
445
+ self._sync_fetch_relationships(entities, fetch_rel_entities, fetch_concept_rels)
446
+
447
+ for entity in all_entities_to_modify:
448
+ entity.request["is_temporary"] = False
449
+ entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
450
+
451
+ for entity in entities:
452
+ entity.sync_params = {}
453
+
454
+ def _find_attachables_to_write(self, entities) -> list:
455
+ attachables_to_write = []
456
+ for entity in entities:
457
+ if entity.sync_params.get(NifiContextManager.SyncFlag.WRITE_CONTENTS):
458
+ if entity.contents:
459
+ attachables_to_write.append(entity)
460
+ return attachables_to_write
461
+
462
+ def _sync_write_attachables(self, attachables_to_write):
463
+ for file in attachables_to_write:
464
+ if not file.contents:
465
+ continue
466
+ old_contents = file._contents
467
+ write_attachment.sync(
468
+ os_workspace=file.write_os_workspace,
469
+ os_entity_uid=file.record["os_entity_uid"],
470
+ entity_type=file.record["os_concept"],
471
+ filetype=file.record["os_item_content_type"],
472
+ file=file.contents,
473
+ client=self.client,
474
+ )
475
+ file._contents = WorkspaceAttachmentContents(
476
+ workspace_id=file.record['os_workspace'],
477
+ entity_id=file.record['os_entity_uid'],
478
+ client=self.client,
479
+ entity_type=file.record["os_concept"],
480
+ filetype=file.record["os_item_content_type"]
481
+ )
482
+ if isinstance(old_contents, TemporaryAttachmentContents):
483
+ try:
484
+ old_contents.delete()
485
+ except Exception:
486
+ pass
487
+
488
+ def _sync_upsert_entities(self, entities_to_upsert):
489
+ if not entities_to_upsert:
490
+ return
491
+ new_entities = upsert_entities.sync(
492
+ [entity.write_os_workspace for entity, _ in entities_to_upsert],
493
+ [
494
+ {
495
+ "entity_type": entity.record["os_concept"],
496
+ "os_entity_uid": entity.record["os_entity_uid"],
497
+ "os_last_updated_at": entity.request["entity_timestamp"],
498
+ "fields": {k: entity.record.get(k) for k in fields},
499
+ }
500
+ for entity, fields in entities_to_upsert
501
+ ],
502
+ client=self.client,
503
+ )
504
+ new_entities = {e["os_entity_uid"]: e for e in new_entities}
505
+ for entity, _ in entities_to_upsert:
506
+ entity.record = {**entity.record, **new_entities[entity.record["os_entity_uid"]]}
507
+ entity.record["entity_id"] = entity.record["os_entity_uid"]
508
+ entity.record["entity_type"] = entity.record["os_concept"]
509
+ entity.record["entity_label"] = entity.label
510
+ entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
511
+ entity.request["is_temporary"] = False
512
+
513
+ def _find_relationships_to_fetch(self, entities) -> dict:
445
514
  fetch_relationships_entities = {}
446
515
  fetch_concept_relationships = {}
447
- # FIND FILES TO WRITE
448
- for entity in entities:
449
- if entity.is_child_concept("os_attachable"):
450
- has_write_flag = entity.sync_params.get(NifiContextManager.SyncFlag.WRITE_CONTENTS)
451
- is_temporary = entity.request.get("is_temporary")
452
- if is_temporary:
453
- if entity._contents and not isinstance(entity._contents, WorkspaceAttachmentContents):
454
- files_to_write.append(entity)
455
- elif has_write_flag:
456
- if entity.contents:
457
- files_to_write.append(entity)
458
- # FIND ENTITIES TO UPSERT
459
- self._find_entities_to_upsert(entities, entities_to_upsert, reserved_fields)
460
- # FIND RELATIONSHIPS TO FETCH
461
516
  for entity in entities:
462
517
  if entity.sync_params.get(NifiContextManager.SyncFlag.FETCH_RELATIONSHIPS):
463
518
  concept_name = entity.record["entity_type"]
@@ -473,142 +528,19 @@ class NifiContextManager(object):
473
528
  )
474
529
  for k in fetch_concept_relationships.keys():
475
530
  fetch_concept_relationships[k] = list(fetch_concept_relationships[k])
476
- # PROTECT AGAINST RE-INDEX OPS
477
- all_entities_to_modify = (
478
- files_to_write + [e[0] for e in entities_to_upsert]
479
- )
480
- with self.reindex_lock(all_entities_to_modify):
481
- # WRITE FILES
482
- if files_to_write:
483
- for file in files_to_write:
484
- if not file.contents:
485
- continue
486
- old_contents = file._contents
487
- new_file_record = write_file.sync(
488
- file.write_os_workspace,
489
- "./" + file.record["os_item_name"],
490
- file.record["os_item_content_type"],
491
- file.contents,
492
- file.record["os_entity_uid"],
493
- file.record["os_parent_folder"],
494
- client=self.client,
495
- )
496
- file.record = {**file.record, **new_file_record}
497
- file.record["entity_id"] = file.record["os_entity_uid"]
498
- file.record["entity_type"] = file.record["os_concept"]
499
- file.record["entity_label"] = file.label
500
- file.request["is_temporary"] = False
501
- file.request["entity_timestamp"] = file.record["os_last_updated_at"]
502
- file._contents = WorkspaceAttachmentContents(
503
- workspace_id=file.record['os_workspace'],
504
- entity_id=file.record['os_entity_uid'],
505
- client=self.client,
506
- entity_type=file.record["os_concept"],
507
- filetype=file.record["os_item_content_type"]
508
- )
509
- file.request["contents_pointer"] = {
510
- "location": ContentsLocation.WORKSPACE_ATTACHMENT.value,
511
- "pointer": f"{file.record['os_workspace']}/{file.record['os_entity_uid']}",
512
- "entity_type": file.record["os_concept"],
513
- "filetype": file.record["os_item_content_type"]
514
- }
515
- if isinstance(old_contents, TemporaryAttachmentContents):
516
- try:
517
- old_contents.delete()
518
- except Exception:
519
- pass
520
- # UPSERT ENTITIES
521
- if entities_to_upsert:
522
- new_entities = upsert_entities.sync(
523
- [entity.write_os_workspace for entity, _ in entities_to_upsert],
524
- [
525
- {
526
- "entity_type": entity.record["os_concept"],
527
- "os_entity_uid": entity.record["os_entity_uid"],
528
- "os_last_updated_at": entity.request["entity_timestamp"],
529
- "fields": {k: entity.record.get(k) for k in fields},
530
- }
531
- for entity, fields in entities_to_upsert
532
- ],
533
- client=self.client,
534
- )
535
- new_entities = {e["os_entity_uid"]: e for e in new_entities}
536
- for entity, _ in entities_to_upsert:
537
- entity.record = {
538
- **entity.record,
539
- **new_entities[entity.record["os_entity_uid"]],
540
- }
541
- entity.record["entity_id"] = entity.record["os_entity_uid"]
542
- entity.record["entity_type"] = entity.record["os_concept"]
543
- entity.record["entity_label"] = entity.label
544
- entity.request["is_temporary"] = False
545
- entity.request["entity_timestamp"] = entity.record["os_last_updated_at"]
546
- # FETCH RELATIONSHIPS
547
- """
548
- if fetch_relationships_entities:
549
- relationship_mappings_info = relationship_mappings.sync_detailed(
550
- client=self.client
551
- ).parsed.data.to_dict()
552
- expanded_entities, _ = safe_async_run(
553
- expand_entities(
554
- [e.record for e in entities],
555
- self.ontology,
556
- relationship_mappings_info,
557
- self.client,
558
- fetch_concept_relationships,
559
- )
560
- )
561
- expanded_entities = {e[0]["os_entity_uid"]: e for e in expanded_entities}
562
- for entity in entities:
563
- found_entities = expanded_entities.get(entity.record["os_entity_uid"])
564
- if found_entities:
565
- for rel, target in found_entities[1]:
566
- is_mtm = bool(
567
- rel.get("os_entity_uid_from")
568
- and rel.get("os_entity_uid_to")
569
- )
570
- rel_type = "mtm" if is_mtm else "otm"
571
- child_entity, child_rel = entity.add_child_entity(
572
- target["os_workspace"],
573
- target["os_concept"],
574
- target,
575
- relationship=RelationshipName(name=rel["os_relationship_name"], type=rel_type),
576
- )
577
- child_entity.record = {**child_entity.record, **target}
578
- child_entity.record["entity_id"] = child_entity.record[
579
- "os_entity_uid"
580
- ]
581
- child_entity.uid = child_entity.record["os_entity_uid"]
582
- child_entity.request["is_temporary"] = False
583
- child_entity.request["entity_timestamp"] = target.get(
584
- "os_last_updated_at"
585
- )
586
- if not is_mtm:
587
- child_rel.record["os_entity_uid_to"] = child_entity.record[
588
- "os_entity_uid"
589
- ]
590
- else:
591
- child_rel.record = {**child_rel.record, **rel}
592
- child_rel.record["entity_id"] = child_rel.record[
593
- "os_entity_uid"
594
- ]
595
- child_rel.uid = child_rel.record["os_entity_uid"]
596
- child_rel.request["is_temporary"] = bool(
597
- rel.get("os_entity_uid")
598
- )
599
- child_rel.request["entity_timestamp"] = rel.get(
600
- "os_last_updated_at"
601
- )
602
- """
603
- # CLEAN SYNC PARAMS
604
- for entity in entities:
605
- entity.sync_params = {}
531
+ return fetch_relationships_entities, fetch_concept_relationships
532
+
533
+ def _sync_fetch_relationships(self, entities, fetch_relationships_entities, fetch_concept_relationships):
534
+ if not fetch_relationships_entities:
535
+ return
536
+ raise NotImplementedError("Relationship fetching is not yet implemented")
606
537
 
607
- def _find_entities_to_upsert(self, entities, entities_to_upsert, reserved_fields) -> None:
538
+ def _find_entities_to_upsert(self, entities) -> list:
539
+ entities_to_upsert = []
608
540
  for entity in entities:
609
541
  fields = set()
610
542
 
611
- if entity.sync_params.get(NifiContextManager.SyncFlag.UPSERT_ENTITY_ALL) or entity.request["is_temporary"]:
543
+ if entity.sync_params.get(NifiContextManager.SyncFlag.UPSERT_ENTITY_ALL):
612
544
  fields = fields.union(set(list(entity.record.keys())))
613
545
 
614
546
  if entity.sync_params.get(NifiContextManager.SyncFlag.UPSERT_ENTITY_SPECIFIC_FIELDS):
@@ -622,7 +554,8 @@ class NifiContextManager(object):
622
554
  )
623
555
  )
624
556
  if fields:
625
- entities_to_upsert.append((entity, [f for f in list(fields) if f not in reserved_fields]))
557
+ entities_to_upsert.append((entity, [f for f in list(fields) if f not in OS_RESERVED_FIELDS]))
558
+ return entities_to_upsert
626
559
 
627
560
  def __exit__(self, exc_type, exc_val, exc_tb):
628
561
  if exc_val is not None:
@@ -743,15 +676,10 @@ class NifiEntity(object):
743
676
 
744
677
  @property
745
678
  def contents(self) -> Optional[Contents]:
746
- if not self._contents:
747
- contents_pointer = self.contents_pointer
748
- if not contents_pointer:
749
- return None
750
- self._contents = Contents.from_locator(contents_pointer, client=self.context.client)
751
679
  return self._contents
752
680
 
753
681
  @contents.setter
754
- def contents(self, new_contents: Optional[Union[Contents, bytes]]):
682
+ def contents(self, new_contents: Optional[Contents]):
755
683
  self._contents = new_contents
756
684
 
757
685
  @property
@@ -796,11 +724,17 @@ class NifiEntity(object):
796
724
 
797
725
  @property
798
726
  def label(self):
727
+ # dummy ontology from our cached data, compatible with get_label()
728
+ entity_type = self.record["entity_type"]
729
+ parents = self.request["ontology_info"]["parents"]
799
730
  label_keys = self.request["ontology_info"]["label_keys"]
800
- label = " ".join([(self.record.get(field) or "") for field in label_keys]).strip()
801
- if not label:
802
- label = None
803
- return label
731
+ ontology = {
732
+ "concepts": {
733
+ entity_type: {"parents": parents, "labelKeys": label_keys},
734
+ **{p: {"parents": [], "labelKeys": []} for p in parents}
735
+ }
736
+ }
737
+ return get_label(self.record, ontology)
804
738
 
805
739
  @property
806
740
  def filepath(self):
@@ -912,11 +846,12 @@ class NifiEntity(object):
912
846
  "label_keys": ont_label_keys,
913
847
  },
914
848
  "entity_timestamp": None,
915
- "sync_params": {},
849
+ "sync_params": {
850
+ NifiContextManager.SyncFlag.UPSERT_ENTITY_ALL.name: True,
851
+ },
916
852
  "nifi_attributes": {},
917
853
  "config": deepcopy(self.request["config"]),
918
854
  "metrics": {},
919
- "contents_pointer": None,
920
855
  "is_temporary": True,
921
856
  "exception": {},
922
857
  "last_processor_name": None,
@@ -991,7 +926,11 @@ class NifiEntity(object):
991
926
  )
992
927
  temp_contents.flush()
993
928
  child_entity._contents = temp_contents
994
- child_entity.request["contents_pointer"] = child_entity._contents.to_locator()
929
+ child_entity.sync_params = recursive_update_dict(
930
+ child_entity.sync_params,
931
+ {NifiContextManager.SyncFlag.WRITE_CONTENTS: True},
932
+ lambda _, v2: v2
933
+ )
995
934
  return child_entity, child_rel
996
935
 
997
936
  def add_mtm_relationship(
@@ -1127,15 +1066,13 @@ class NifiEntity(object):
1127
1066
  fragment_uid = child_entity.record["os_entity_uid"]
1128
1067
  fragment_type = child_entity.record["os_concept"]
1129
1068
  if previous_fragment_uid:
1130
- prev_rel = previous_fragment_relationship or PREVIOUS_FRAGMENT_RELATIONSHIP
1131
- self._add_relationship(
1069
+ prev_rel = self._add_relationship(
1132
1070
  os_workspace, fragment_uid, fragment_type,
1133
1071
  previous_fragment_uid, os_entity_type,
1134
1072
  previous_fragment_relationship, {}, previous_fragment_relationship_uid,
1135
1073
  )
1136
1074
  if next_fragment_uid:
1137
- next_rel = next_fragment_relationship or NEXT_FRAGMENT_RELATIONSHIP
1138
- self._add_relationship(
1075
+ next_rel = self._add_relationship(
1139
1076
  os_workspace, fragment_uid, fragment_type,
1140
1077
  next_fragment_uid, os_entity_type,
1141
1078
  next_fragment_relationship, {}, next_fragment_relationship_uid,
@@ -13,3 +13,15 @@ def get_label_keys(type, ontology):
13
13
  continue
14
14
  label_keys[label_key] = None
15
15
  return list(label_keys.keys())
16
+
17
+ def get_label(record, ontology):
18
+ if record.get("os_materialized_label"):
19
+ return record.get("os_materialized_label")
20
+ if record.get("os_label"):
21
+ return record.get("os_label")
22
+ label_keys = get_label_keys(record["entity_type"], ontology)
23
+ fields = [record.get(field) for field in label_keys]
24
+ fields = [f for f in fields if f is not None]
25
+ fields = [str(f) for f in fields if f]
26
+ label = " ".join(fields)
27
+ return label or None