streamlit-octostar-utils 0.4.2.dev23__tar.gz → 0.4.2.dev25__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.dev23 → streamlit_octostar_utils-0.4.2.dev25}/PKG-INFO +1 -1
  2. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/pyproject.toml +1 -1
  3. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/celery.py +39 -30
  4. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/nifi.py +10 -1
  5. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/LICENSE +0 -0
  6. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/README.md +0 -0
  7. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/__init__.py +0 -0
  8. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/__init__.py +0 -0
  9. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/contents.py +0 -0
  10. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/fastapi.py +0 -0
  11. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parallelism.py +0 -0
  12. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/__init__.py +0 -0
  13. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/combine_fields.py +0 -0
  14. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/entities_parser.py +0 -0
  15. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/generics.py +0 -0
  16. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/info.py +0 -0
  17. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py +0 -0
  18. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/matches.py +0 -0
  19. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/parameters.py +0 -0
  20. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/rules.py +0 -0
  21. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/api_crafter/parser/signals.py +0 -0
  22. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/__init__.py +0 -0
  23. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/dict.py +0 -0
  24. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/filetypes.py +0 -0
  25. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/threading/__init__.py +0 -0
  26. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/threading/key_queue.py +0 -0
  27. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/core/timestamp.py +0 -0
  28. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/nlp/__init__.py +0 -0
  29. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/nlp/custom_recognizers.py +0 -0
  30. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/nlp/language.py +0 -0
  31. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/nlp/ner.py +0 -0
  32. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/octostar/__init__.py +0 -0
  33. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/octostar/client.py +0 -0
  34. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/octostar/context.py +0 -0
  35. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/octostar/permissions.py +0 -0
  36. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/ontology/__init__.py +0 -0
  37. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/ontology/inheritance.py +0 -0
  38. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/ontology/relationships.py +0 -0
  39. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/ontology/validation.py +0 -0
  40. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/style/__init__.py +0 -0
  41. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/style/common.py +0 -0
  42. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/threading/__init__.py +0 -0
  43. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/threading/async_task_manager.py +0 -0
  44. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/streamlit_octostar_utils/threading/session_callback_manager.py +0 -0
  45. {streamlit_octostar_utils-0.4.2.dev23 → streamlit_octostar_utils-0.4.2.dev25}/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.dev23
3
+ Version: 0.4.2.dev25
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.23"
8
+ version = "0.4.2-dev.25"
9
9
  description = ""
10
10
  license = "MIT"
11
11
  authors = ["Octostar"]
@@ -129,7 +129,10 @@ class CeleryExecutor(object):
129
129
  self.get_thread_pool = None
130
130
  self.set_thread_pool = None
131
131
  self.io_thread_pool = None
132
- self.queue_threadlocks = {k: threading.Lock() for k in self.queue_config.keys()}
132
+ self.queue_semaphores = {
133
+ k: threading.Semaphore(v.max_tasks_in_queue) if v.max_tasks_in_queue else None
134
+ for k, v in self.queue_config.items()
135
+ }
133
136
 
134
137
  # Folder setup
135
138
  self.base_folder = Path(base_folder).resolve()
@@ -576,36 +579,23 @@ class CeleryExecutor(object):
576
579
 
577
580
  return decorator
578
581
 
579
- async def send_task(self, task_fn, args=[], kwargs={}, **options) -> str:
582
+ async def send_task(self, task_fn, args=None, kwargs=None, **options) -> str:
583
+ args = args if args is not None else []
584
+ kwargs = kwargs if kwargs is not None else {}
580
585
  if self.app.conf.task_always_eager and "dev_preload" not in self.app.conf:
581
586
  self.preload_on_worker_init()
582
587
  self.app.conf.dev_preload = True
583
588
 
584
- def _reserve_queue_slot(queue_name):
589
+ def _check_queue_llen(queue_name):
585
590
  if self._queue_stalled.get(queue_name, False):
586
591
  raise CeleryExecutor.QueueStalledException(
587
592
  f"Queue '{queue_name}' is stalled. Service temporarily unavailable."
588
593
  )
589
- limit = self.queue_config[queue_name].max_tasks_in_queue
590
- if limit:
591
- reservation_key = f"queue:reserved:{queue_name}"
592
- with self.queue_threadlocks[queue_name]:
593
- queue_count = self.redis_client.llen(queue_name)
594
- reserved_count = int(self.redis_client.get(reservation_key) or 0)
595
- total_count = queue_count + reserved_count
596
- if total_count >= limit:
597
- raise CeleryExecutor.QueueFullException(
598
- f"Queue '{queue_name}' has reached its limit of {limit} tasks!"
599
- )
600
- self.redis_client.incr(reservation_key)
601
- return True
602
- return False
603
-
604
- def _release_queue_slot(queue_name):
605
- limit = self.queue_config[queue_name].max_tasks_in_queue
606
- if limit:
607
- reservation_key = f"queue:reserved:{queue_name}"
608
- self.redis_client.decr(reservation_key)
594
+ if self.redis_client.llen(queue_name) >= self.queue_config[queue_name].max_tasks_in_queue:
595
+ raise CeleryExecutor.QueueFullException(
596
+ f"Queue '{queue_name}' has reached its limit of "
597
+ f"{self.queue_config[queue_name].max_tasks_in_queue} tasks!"
598
+ )
609
599
 
610
600
  def _write_task_data(in_folder, task_args, task_kwargs, task_id):
611
601
  serialized_data = CelerySerialized(
@@ -629,11 +619,22 @@ class CeleryExecutor(object):
629
619
  queue_name = self.app.conf.task_default_routing_key
630
620
  queue_name = getattr(task_fn, "queue", queue_name)
631
621
  queue_name = options.get("queue", queue_name)
632
- reserved = False
622
+
623
+ sem = self.queue_semaphores.get(queue_name)
624
+ acquired = False
625
+ if sem is not None:
626
+ if not sem.acquire(blocking=False):
627
+ raise CeleryExecutor.QueueFullException(
628
+ f"Queue '{queue_name}' has reached its limit of "
629
+ f"{self.queue_config[queue_name].max_tasks_in_queue} tasks!"
630
+ )
631
+ acquired = True
632
+
633
633
  try:
634
- reserved = await asyncio.get_running_loop().run_in_executor(
635
- self.set_thread_pool, _reserve_queue_slot, queue_name
636
- )
634
+ if acquired:
635
+ await asyncio.get_running_loop().run_in_executor(
636
+ self.set_thread_pool, _check_queue_llen, queue_name
637
+ )
637
638
  await asyncio.get_running_loop().run_in_executor(
638
639
  self.io_thread_pool,
639
640
  _write_task_data,
@@ -652,9 +653,15 @@ class CeleryExecutor(object):
652
653
  logger.info(f"Cancelling task {task_id} due to disconnect!")
653
654
  await self.terminate_task(task_id)
654
655
  raise
656
+ except Exception:
657
+ try:
658
+ await self.terminate_task(task_id)
659
+ except Exception:
660
+ pass
661
+ raise
655
662
  finally:
656
- if reserved:
657
- await asyncio.get_running_loop().run_in_executor(self.set_thread_pool, _release_queue_slot, queue_name)
663
+ if acquired:
664
+ sem.release()
658
665
  return task_id
659
666
 
660
667
  async def terminate_task(self, task_id):
@@ -737,7 +744,9 @@ class CeleryExecutor(object):
737
744
  )
738
745
  return result
739
746
 
740
- async def send_and_wait_task(self, task_fn, args=[], kwargs={}, timeout=60, **options):
747
+ async def send_and_wait_task(self, task_fn, args=None, kwargs=None, timeout=60, **options):
748
+ args = args if args is not None else []
749
+ kwargs = kwargs if kwargs is not None else {}
741
750
  task_id = await self.send_task(task_fn, args, kwargs, **options)
742
751
  ready = False
743
752
  state = None
@@ -25,7 +25,7 @@ from ..core.dict import recursive_update_dict, travel_dict, jsondict_hash
25
25
  from ..core.timestamp import now, string_to_datetime
26
26
  from .fastapi import DefaultErrorRoute, Route
27
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
+ from .contents import Contents, WorkspaceAttachmentContents, TemporaryAttachmentContents, MemoryContents
29
29
 
30
30
 
31
31
  class RelationshipName(BaseModel):
@@ -49,6 +49,8 @@ OS_RESERVED_FIELDS = [
49
49
  "entity_label", "os_created_at", "os_created_by",
50
50
  "os_last_updated_at", "os_last_updated_by",
51
51
  ]
52
+ MAX_IN_MEMORY_SIZE_BYTES = 5_242_880
53
+
52
54
 
53
55
  class NifiProxyEntityModel(BaseModel):
54
56
  entity_id: str
@@ -957,6 +959,12 @@ class NifiEntity(object):
957
959
  )
958
960
  if isinstance(file, Contents):
959
961
  child_entity._contents = file
962
+ elif len(file) <= MAX_IN_MEMORY_SIZE_BYTES:
963
+ child_entity._contents = MemoryContents(
964
+ entity_type=os_entity_type,
965
+ filetype=filetype,
966
+ initial_data=file,
967
+ )
960
968
  else:
961
969
  temp_filename = f"tmp_{child_entity.record['os_entity_uid']}"
962
970
  temp_contents = TemporaryAttachmentContents(
@@ -965,6 +973,7 @@ class NifiEntity(object):
965
973
  filename=temp_filename,
966
974
  client=self.context.client,
967
975
  )
976
+ temp_contents.truncate(0)
968
977
  temp_contents.write(file)
969
978
  temp_contents.flush()
970
979
  child_entity._contents = temp_contents