streamlit-octostar-utils 0.4.2.dev11__tar.gz → 0.4.2.dev13__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.dev11 → streamlit_octostar_utils-0.4.2.dev13}/PKG-INFO +1 -1
  2. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/pyproject.toml +1 -1
  3. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/contents.py +52 -139
  4. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/nifi.py +4 -2
  5. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/LICENSE +0 -0
  6. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/README.md +0 -0
  7. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/__init__.py +0 -0
  8. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
  9. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/celery.py +0 -0
  10. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
  11. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
  12. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
  13. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/combine_fields.py +0 -0
  14. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/entities_parser.py +0 -0
  15. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
  16. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
  17. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py +0 -0
  18. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
  19. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
  20. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
  21. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
  22. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/__init__.py +0 -0
  23. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/dict.py +0 -0
  24. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/filetypes.py +0 -0
  25. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
  26. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
  27. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/core/timestamp.py +0 -0
  28. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/nlp/__init__.py +0 -0
  29. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
  30. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/nlp/language.py +0 -0
  31. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/nlp/ner.py +0 -0
  32. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/octostar/__init__.py +0 -0
  33. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/octostar/client.py +0 -0
  34. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/octostar/context.py +0 -0
  35. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/octostar/permissions.py +0 -0
  36. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/ontology/__init__.py +0 -0
  37. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/ontology/inheritance.py +0 -0
  38. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/ontology/relationships.py +0 -0
  39. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/ontology/validation.py +0 -0
  40. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/style/__init__.py +0 -0
  41. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/style/common.py +0 -0
  42. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/threading/__init__.py +0 -0
  43. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
  44. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
  45. {streamlit_octostar_utils-0.4.2.dev11 → streamlit_octostar_utils-0.4.2.dev13}/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.dev11
3
+ Version: 0.4.2.dev13
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.11"
8
+ version = "0.4.2-dev.13"
9
9
  description = ""
10
10
  license = "MIT"
11
11
  authors = ["Octostar"]
@@ -18,7 +18,6 @@ from abc import ABC, abstractmethod
18
18
  from typing import Optional, Dict, Any, List
19
19
  from enum import Enum
20
20
  import base64
21
- import httpx
22
21
  import logging
23
22
  from io import BytesIO, SEEK_SET, SEEK_CUR, SEEK_END
24
23
 
@@ -710,20 +709,18 @@ class TemporaryAttachmentContents(Contents):
710
709
  """
711
710
  Contents implementation for Octostar temporary blob storage.
712
711
 
713
- All I/O goes through presigned S3 URLs:
714
- - Reads use get_temporary_blob_url() for presigned download URLs
715
- - Writes use request_temporary_blob_url() for presigned upload URLs
712
+ Uses the SDK's ``read_temporary_blob`` / ``write_temporary_blob`` /
713
+ ``delete_temporary_blob`` functions which handle presigned URLs internally.
714
+
715
+ - Reads use ``read_temporary_blob.sync()`` with ``byte_range`` for efficient
716
+ partial reads and ``headers_only=True`` for HEAD metadata.
717
+ - Writes are buffered locally and uploaded on ``flush()`` via
718
+ ``write_temporary_blob.sync()``.
716
719
 
717
720
  Temporary blobs are keyed by filename (not workspace/entity), and are not
718
721
  associated with any workspace entity. Use WorkspaceAttachmentContents for that.
719
-
720
- Presigned URL Handling:
721
- - Download URLs are cached and refreshed automatically on 403 (expired).
722
722
  """
723
723
 
724
- DEFAULT_URL_TIMEOUT = 120
725
- MAX_RETRIES = 3
726
-
727
724
  def __init__(
728
725
  self,
729
726
  entity_type: Optional[str] = None,
@@ -741,150 +738,70 @@ class TemporaryAttachmentContents(Contents):
741
738
  self._modified = False
742
739
  self._position = 0
743
740
  self._size: Optional[int] = None
744
- self._download_url: Optional[str] = None
745
- self._http_client: Optional[httpx.Client] = None
746
-
747
- # ==================== Presigned URL management ====================
748
-
749
- def _ensure_http_client(self):
750
- """Ensure the shared httpx.Client is initialized."""
751
- if not self._http_client:
752
- self._http_client = httpx.Client(timeout=self.DEFAULT_URL_TIMEOUT)
753
-
754
- def _ensure_download_url(self):
755
- """Ensure a download URL is cached, fetching one if needed."""
756
- if not self._download_url:
757
- self._download_url = self._refresh_download_url()
758
741
 
759
- def _refresh_download_url(self) -> str:
760
- from octostar.utils.workspace import get_temporary_blob_url
761
-
762
- return get_temporary_blob_url.sync(
763
- filename=self._filename,
764
- client=self._client
765
- )
766
-
767
- def _get_upload_info(self) -> Dict[str, Any]:
768
- from octostar.utils.workspace import request_temporary_blob_url
769
-
770
- return request_temporary_blob_url.sync(
771
- filename=self._filename,
772
- client=self._client
773
- )
774
-
775
- # ==================== Remote operations ====================
742
+ # ==================== Remote operations via SDK ====================
776
743
 
777
744
  def _fetch_size(self) -> int:
778
- """Fetch remote content size via HEAD request with presigned URL."""
745
+ """Fetch the remote content size via a HEAD request."""
779
746
  if self._size is not None:
780
747
  return self._size
781
748
 
782
- self._ensure_download_url()
783
- self._ensure_http_client()
784
-
785
- assert self._http_client is not None
786
- assert self._download_url is not None
787
-
788
- for attempt in range(self.MAX_RETRIES):
789
- response = self._http_client.head(self._download_url)
790
- if response.status_code == 200:
791
- self._size = int(response.headers.get('content-length', 0))
792
- return self._size
793
- elif response.status_code == 403:
794
- _logger.debug(
795
- "Presigned URL expired while fetching size, refreshing... (attempt %d/%d)",
796
- attempt + 1, self.MAX_RETRIES,
797
- )
798
- self._download_url = self._refresh_download_url()
799
- continue
800
- else:
801
- response.raise_for_status()
802
-
803
- raise ConnectionError(
804
- f"Failed to fetch file size after {self.MAX_RETRIES} attempts (URL kept expiring)"
805
- )
749
+ try:
750
+ from octostar.utils.workspace import read_temporary_blob
751
+
752
+ headers = read_temporary_blob.sync(
753
+ filename=self._filename,
754
+ headers_only=True,
755
+ client=self._client,
756
+ )
757
+ self._size = int(headers.get('content-length', 0))
758
+ except Exception:
759
+ self._size = 0
760
+ return self._size
806
761
 
807
762
  def _read_range(self, start: int, end: int) -> bytes:
808
- """Read a specific byte range via presigned URL with Range header."""
809
- self._ensure_download_url()
810
- self._ensure_http_client()
811
- assert self._http_client is not None
812
- assert self._download_url is not None
813
-
814
- headers = {"Range": f"bytes={start}-{end}"}
763
+ """Read a specific byte range from the remote blob."""
764
+ from octostar.utils.workspace import read_temporary_blob
815
765
 
816
- for attempt in range(self.MAX_RETRIES):
817
- response = self._http_client.get(self._download_url, headers=headers)
818
-
819
- if response.status_code == 206:
820
- return response.content
821
- elif response.status_code == 416:
822
- return b""
823
- elif response.status_code == 403:
824
- _logger.debug(
825
- "Presigned URL expired at byte %d, refreshing... (attempt %d/%d)",
826
- start, attempt + 1, self.MAX_RETRIES,
827
- )
828
- self._download_url = self._refresh_download_url()
829
- continue
830
- else:
831
- response.raise_for_status()
832
- return response.content
833
-
834
- raise ConnectionError(
835
- f"Failed to read range {start}-{end} after {self.MAX_RETRIES} attempts (URL kept expiring)"
766
+ data = read_temporary_blob.sync(
767
+ filename=self._filename,
768
+ decode=False,
769
+ byte_range=(start, end),
770
+ client=self._client,
836
771
  )
772
+ return data if isinstance(data, bytes) else data.encode()
837
773
 
838
774
  def _load_full(self):
839
- """Load the entire remote content into memory buffer via presigned URL."""
775
+ """Load the entire remote blob into the in-memory buffer."""
840
776
  if self._fully_loaded:
841
777
  return
842
778
 
843
- self._ensure_download_url()
844
- self._ensure_http_client()
845
- assert self._http_client is not None
846
- assert self._download_url is not None
847
-
848
- for attempt in range(self.MAX_RETRIES):
849
- response = self._http_client.get(self._download_url)
850
- if response.status_code == 200:
851
- data = response.content
852
- self._buffer = BytesIO(data)
853
- self._fully_loaded = True
854
- self._size = len(data)
855
- self._buffer.seek(self._position, SEEK_SET)
856
- return
857
- elif response.status_code == 403:
858
- _logger.debug(
859
- "Presigned URL expired during full load, refreshing... (attempt %d/%d)",
860
- attempt + 1, self.MAX_RETRIES,
861
- )
862
- self._download_url = self._refresh_download_url()
863
- continue
864
- else:
865
- response.raise_for_status()
779
+ try:
780
+ from octostar.utils.workspace import read_temporary_blob
781
+
782
+ data = read_temporary_blob.sync(
783
+ filename=self._filename,
784
+ decode=False,
785
+ client=self._client,
786
+ )
787
+ except Exception:
788
+ # Blob may not exist yet — start with empty buffer
789
+ data = b""
866
790
 
867
- raise ConnectionError(
868
- f"Failed to load full content after {self.MAX_RETRIES} attempts (URL kept expiring)"
869
- )
791
+ self._buffer = BytesIO(data)
792
+ self._fully_loaded = True
793
+ self._size = len(data)
794
+ self._buffer.seek(self._position, SEEK_SET)
870
795
 
871
796
  def _upload_data(self, data: bytes):
872
- """Upload data to temporary storage via presigned POST URL."""
873
- upload_info = self._get_upload_info()
874
- upload_url = upload_info["url"]
875
- upload_fields = upload_info.get("fields", {})
876
-
877
- self._ensure_http_client()
878
- assert self._http_client is not None
879
- file_obj = BytesIO(data)
797
+ """Upload data via the SDK write_temporary_blob."""
798
+ from octostar.utils.workspace import write_temporary_blob
880
799
 
881
- response = self._http_client.post(
882
- upload_url,
883
- data=upload_fields,
884
- files={"file": file_obj},
800
+ write_temporary_blob.sync(
801
+ filename=self._filename,
802
+ file=data,
803
+ client=self._client,
885
804
  )
886
- if response.status_code not in (200, 204):
887
- response.raise_for_status()
888
805
 
889
806
  # ==================== FileIO Interface ====================
890
807
 
@@ -952,7 +869,7 @@ class TemporaryAttachmentContents(Contents):
952
869
  return self._position
953
870
 
954
871
  def flush(self):
955
- """Upload buffer to temporary storage via presigned URL, then invalidate cache."""
872
+ """Upload buffer to temporary storage, then invalidate cache."""
956
873
  if self._buffer:
957
874
  self._buffer.flush()
958
875
 
@@ -972,7 +889,6 @@ class TemporaryAttachmentContents(Contents):
972
889
  self._fully_loaded = False
973
890
  self._position = 0
974
891
  self._size = None
975
- self._download_url = None
976
892
 
977
893
  def close(self):
978
894
  if not self._closed:
@@ -980,9 +896,6 @@ class TemporaryAttachmentContents(Contents):
980
896
  self.flush()
981
897
  if self._buffer:
982
898
  self._buffer.close()
983
- if self._http_client:
984
- self._http_client.close()
985
- self._http_client = None
986
899
  super().close()
987
900
 
988
901
  def truncate(self, size: Optional[int] = None) -> int:
@@ -524,9 +524,11 @@ class NifiContextManager(object):
524
524
  fetch_relationships_entities = {}
525
525
  fetch_concept_relationships = {}
526
526
  for entity in entities:
527
- if entity.sync_params.get(NifiContextManager.SyncFlag.FETCH_RELATIONSHIPS):
527
+ rels_to_fetch = (
528
+ entity.sync_params.get(NifiContextManager.SyncFlag.FETCH_RELATIONSHIPS) or {}
529
+ ).get("relationships") or []
530
+ if rels_to_fetch:
528
531
  concept_name = entity.record["entity_type"]
529
- rels_to_fetch = entity.sync_params.get(NifiContextManager.SyncFlag.FETCH_RELATIONSHIPS, [])
530
532
  for rel in rels_to_fetch:
531
533
  if rel not in fetch_relationships_entities:
532
534
  fetch_relationships_entities[rel] = []