streamlit-octostar-utils 0.1.7a8__py3-none-any.whl → 0.1.7a10__py3-none-any.whl

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.
@@ -493,18 +493,9 @@ class CeleryExecutor(object):
493
493
  task_id,
494
494
  )
495
495
 
496
- try:
497
- await asyncio.get_running_loop().run_in_executor(
498
- self.set_thread_pool, _send_task, task_fn, task_id, options
499
- )
500
-
501
- except CeleryExecutor.QueueFullException as e:
502
- if os.path.isfile(os.path.join(self.in_folder, task_id)):
503
- with RedisFileLock(self.redis_client, os.path.join(self.in_folder, task_id)):
504
- os.remove(os.path.join(self.in_folder, task_id))
505
-
506
- logger.warning(f"Queue full exception: {str(e)}")
507
- return None
496
+ await asyncio.get_running_loop().run_in_executor(
497
+ self.set_thread_pool, _send_task, task_fn, task_id, options
498
+ )
508
499
 
509
500
  except asyncio.CancelledError:
510
501
  logger.info(f"Cancelling task {task_id} due to disconnect!")
@@ -694,20 +685,26 @@ class CeleryErrorRoute(DefaultErrorRoute):
694
685
  DEFAULT_SILENCED_EXCEPTIONS = {CeleryExecutor.QueueFullException: lambda exc: True}
695
686
 
696
687
  def add_default_exceptions_handler(
697
- fs_app,
698
- debug=False,
699
- excs_to_status_codes=None,
700
- silenced_excs=None,
701
- log_filter=None,
688
+ fs_app,
689
+ debug=False,
690
+ excs_to_status_codes=None,
691
+ silenced_excs=None,
702
692
  ):
703
- if excs_to_status_codes is None:
704
- excs_to_status_codes = {
705
- **DefaultErrorRoute.DEFAULT_STATUS_CODE_MAPPINGS,
706
- **CeleryErrorRoute.DEFAULT_STATUS_CODE_MAPPINGS,
707
- }
708
- if silenced_excs is None:
709
- silenced_excs = {
710
- **DefaultErrorRoute.DEFAULT_SILENCED_EXCEPTIONS,
711
- **CeleryErrorRoute.DEFAULT_SILENCED_EXCEPTIONS,
712
- }
713
- DefaultErrorRoute.add_default_exceptions_handler(fs_app, debug, excs_to_status_codes)
693
+ extra_status = {CeleryExecutor.QueueFullException: lambda exc: 429}
694
+ extra_silence = {CeleryExecutor.QueueFullException: lambda exc: True}
695
+
696
+ status_codes = {
697
+ **DefaultErrorRoute.DEFAULT_STATUS_CODE_MAPPINGS,
698
+ **(excs_to_status_codes or {}),
699
+ **extra_status,
700
+ }
701
+
702
+ silenced = {
703
+ **DefaultErrorRoute.DEFAULT_SILENCED_EXCEPTIONS,
704
+ **(silenced_excs or {}),
705
+ **extra_silence,
706
+ }
707
+
708
+ super(CeleryErrorRoute, CeleryErrorRoute).add_default_exceptions_handler(
709
+ fs_app, debug, status_codes, silenced
710
+ )
@@ -241,20 +241,30 @@ class CommonModels(object):
241
241
  headers["Content-Disposition"] += f' filename="{filename}"'
242
242
  return StreamingResponse(zip_buffer, media_type="application/zip", headers=headers)
243
243
 
244
+
244
245
  class ErrorLogFilter(logging.Filter):
245
- def __init__(self, silenced_excs: dict):
246
+ def __init__(self, silenced_excs: dict[type, callable]):
246
247
  super().__init__()
247
248
  self.silenced_excs = silenced_excs
248
-
249
- def filter(self, record):
250
- exc_info = getattr(record, 'exc_info', None)
251
- if exc_info:
252
- if record.exc_info:
253
- exc_type, exc_value, exc_tb = record.exc_info
254
- if exc_value:
255
- for etype, cond in self.silenced_excs.items():
256
- if isinstance(exc_value, etype) and cond(exc_value):
257
- return False
249
+
250
+ def _silenced(self, exc_value) -> bool:
251
+ for etype, cond in self.silenced_excs.items():
252
+ if isinstance(exc_value, etype) and cond(exc_value):
253
+ return True
254
+ return False
255
+
256
+ def filter(self, record: logging.LogRecord) -> bool:
257
+ if record.exc_info:
258
+ exc_type, exc_value, _ = record.exc_info
259
+ if self._silenced(exc_value):
260
+ return False
261
+
262
+ msg = record.getMessage()
263
+ for etype in self.silenced_excs:
264
+ if etype.__name__ in msg:
265
+ if self.silenced_excs[etype](None):
266
+ return False
267
+
258
268
  return True
259
269
 
260
270
 
@@ -304,7 +314,7 @@ class DefaultErrorRoute:
304
314
  },
305
315
  }
306
316
 
307
- def format_error(exc, body=bytes(), debug=False, excs_to_status_codes=DEFAULT_STATUS_CODE_MAPPINGS):
317
+ def format_error(exc, body=b"", debug=False, excs_to_status_codes=DEFAULT_STATUS_CODE_MAPPINGS):
308
318
  """Generic Error Handler"""
309
319
  status_code = 500
310
320
  for exc_type, handler in excs_to_status_codes.items():
@@ -334,10 +344,10 @@ class DefaultErrorRoute:
334
344
  return DefaultErrorRoute.format_error(exc, body, debug, excs_to_status_codes)
335
345
 
336
346
  def add_default_exceptions_handler(
337
- fs_app,
338
- debug=False,
339
- excs_to_status_codes=None,
340
- silenced_excs=None,
347
+ fs_app,
348
+ debug=False,
349
+ excs_to_status_codes=None,
350
+ silenced_excs=None,
341
351
  ):
342
352
  if excs_to_status_codes is None:
343
353
  excs_to_status_codes = DefaultErrorRoute.DEFAULT_STATUS_CODE_MAPPINGS
@@ -345,17 +355,18 @@ class DefaultErrorRoute:
345
355
  silenced_excs = DefaultErrorRoute.DEFAULT_SILENCED_EXCEPTIONS
346
356
 
347
357
  async def _async_handle_error(request: Request, exc: Exception):
348
- return await DefaultErrorRoute.handle_error(request, exc, debug, excs_to_status_codes)
358
+ return await DefaultErrorRoute.handle_error(b"", exc, debug, excs_to_status_codes)
349
359
 
350
360
  # Added all three since FastAPI seems to intercept some exceptions before Exception
351
361
  fs_app.add_exception_handler(RequestValidationError, _async_handle_error)
352
362
  fs_app.add_exception_handler(StarletteHTTPException, _async_handle_error)
353
363
  fs_app.add_exception_handler(Exception, _async_handle_error)
354
-
364
+
355
365
  log_filter = ErrorLogFilter(silenced_excs)
356
- logging.getLogger("uvicorn.error").addFilter(log_filter)
357
- logging.getLogger("uvicorn").addFilter(log_filter)
358
- logging.getLogger("fastapi").addFilter(log_filter)
366
+ for name in ("uvicorn.error", "uvicorn.access", "fastapi", "uvicorn"):
367
+ logging.getLogger(name).addFilter(log_filter)
368
+
369
+ logging.getLogger().addFilter(log_filter)
359
370
 
360
371
  class RequestCancelledMiddleware:
361
372
  def __init__(self, app):
@@ -60,6 +60,10 @@ class EntitiesInvalidReason(Enum):
60
60
  INVALID_REL_TYPE = 20
61
61
  UNKNOWN_UUID = 21
62
62
  WRONG_SOURCE_OR_TARGET_TYPE = 22
63
+
64
+
65
+ EntityDict = dict
66
+ InvalidErrorDict = dict
63
67
 
64
68
 
65
69
  class EntitiesParser(object):
@@ -547,29 +551,42 @@ class EntitiesParser(object):
547
551
  self._get_ontology()
548
552
  if not self.ontology:
549
553
  raise RuntimeError("Ontology could not be fetched for validation!")
554
+ ontology = self.ontology
550
555
  from streamlit_octostar_utils.ontology.validation import (
551
556
  validate_and_format_timbr_type,
552
557
  )
553
558
  from streamlit_octostar_utils.ontology.inheritance import is_child_concept
554
559
 
555
560
  processed_entities = []
556
- processsed_relationships = []
561
+ processed_relationships = []
557
562
  for entity in entities:
558
- if entity.concept_name not in self.ontology["concepts"]:
559
- processed_entities.append((EntitiesInvalidReason.INVALID_TYPE, entity))
560
- continue
563
+ if entity.concept_name not in ontology["concepts"]:
564
+ processed_entities.append(
565
+ (
566
+ EntitiesInvalidReason.INVALID_TYPE,
567
+ entity,
568
+ {"error_message": f"{entity} has invalid concept name"},
569
+ )
570
+ )
561
571
  entity_properties = [
562
- k for k in entity.fields.keys() if not k.startswith("#")
572
+ k
573
+ for k in entity.fields.keys()
574
+ if not k.startswith("#") and k != "extra_fields"
563
575
  ]
564
576
  ontology_properties = {
565
577
  e["property_name"]: e
566
- for e in self.ontology["concepts"][entity.concept_name]["allProperties"]
578
+ for e in ontology["concepts"][entity.concept_name]["allProperties"]
567
579
  }
568
580
  if any(prop not in ontology_properties for prop in entity_properties):
569
581
  processed_entities.append(
570
- (EntitiesInvalidReason.INVALID_PROPERTIES, entity)
582
+ (
583
+ EntitiesInvalidReason.INVALID_PROPERTIES,
584
+ entity,
585
+ {
586
+ "error_message": f"{entity} has invalid entity properties: {str(set(entity_properties) - set(ontology_properties))}"
587
+ },
588
+ )
571
589
  )
572
- continue
573
590
  for prop in entity_properties:
574
591
  try:
575
592
  entity.fields[prop] = validate_and_format_timbr_type(
@@ -577,46 +594,66 @@ class EntitiesParser(object):
577
594
  )
578
595
  except:
579
596
  processed_entities.append(
580
- (EntitiesInvalidReason.INVALID_PROPERTIES, entity)
597
+ (
598
+ EntitiesInvalidReason.INVALID_PROPERTIES,
599
+ entity,
600
+ {
601
+ "error_message": f"{entity} has an invalid property type for property {prop}"
602
+ },
603
+ )
581
604
  )
582
- continue
583
- processed_entities.append((EntitiesInvalidReason.VALID, entity))
605
+ processed_entities.append((EntitiesInvalidReason.VALID, entity, {}))
584
606
  ontology_relationships = {
585
- r["relationship_name"]: r for r in self.ontology["relationships"]
607
+ r["relationship_name"]: r for r in ontology["relationships"]
586
608
  }
587
609
  for rel in relationships:
588
610
  if rel.name not in ontology_relationships.keys():
589
- processsed_relationships.append(
590
- (EntitiesInvalidReason.INVALID_REL_TYPE, rel)
611
+ processed_relationships.append(
612
+ (
613
+ EntitiesInvalidReason.INVALID_REL_TYPE,
614
+ rel,
615
+ {"error_message": f"{rel} relationship name is invalid"},
616
+ )
591
617
  )
592
- continue
593
- entities_by_id = {e.unique_id: e for e in entities}
618
+ entities_by_id = {e[1].unique_id: e[1] for e in processed_entities}
594
619
  if (
595
620
  rel.concept_from not in entities_by_id.keys()
596
621
  or rel.concept_to not in entities_by_id.keys()
597
622
  ):
598
- processsed_relationships.append(
599
- (EntitiesInvalidReason.UNKNOWN_UUID, rel)
623
+ processed_relationships.append(
624
+ (
625
+ EntitiesInvalidReason.UNKNOWN_UUID,
626
+ rel,
627
+ {
628
+ "error_message": f"for {rel}, source concept or target concept are invalid"
629
+ },
630
+ )
600
631
  )
601
- continue
602
632
  ontology_relationship = ontology_relationships[rel.name]
603
633
  rel_concept_types = (
604
634
  entities_by_id[rel.concept_from].concept_name,
605
635
  entities_by_id[rel.concept_to].concept_name,
606
636
  )
607
637
  if not is_child_concept(
608
- rel_concept_types[0], ontology_relationship["concept"], self.ontology
638
+ rel_concept_types[0],
639
+ ontology_relationship["concept"],
640
+ ontology,
609
641
  ) or not is_child_concept(
610
642
  rel_concept_types[1],
611
643
  ontology_relationship["target_concept"],
612
- self.ontology,
644
+ ontology,
613
645
  ):
614
- processsed_relationships.append(
615
- (EntitiesInvalidReason.WRONG_SOURCE_OR_TARGET_TYPE, rel)
646
+ processed_relationships.append(
647
+ (
648
+ EntitiesInvalidReason.WRONG_SOURCE_OR_TARGET_TYPE,
649
+ rel,
650
+ {
651
+ "error_message": f"for {rel}, type for source concept or for target concept is invalid"
652
+ },
653
+ )
616
654
  )
617
- continue
618
- processsed_relationships.append((EntitiesInvalidReason.VALID, rel))
619
- return processed_entities, processsed_relationships
655
+ processed_relationships.append((EntitiesInvalidReason.VALID, rel, {}))
656
+ return processed_entities, processed_relationships
620
657
 
621
658
  def replace_unique_id(self, id_from, id_to, entities, relationships):
622
659
  for entity in entities:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: streamlit-octostar-utils
3
- Version: 0.1.7a8
3
+ Version: 0.1.7a10
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: Octostar
@@ -1,11 +1,11 @@
1
1
  streamlit_octostar_utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
2
2
  streamlit_octostar_utils/api_crafter/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
- streamlit_octostar_utils/api_crafter/celery.py,sha256=3vJ7gDf_WyGrXquuxHNA9ybw1ljRAB_l3wJDNVUZs_0,30213
4
- streamlit_octostar_utils/api_crafter/fastapi.py,sha256=s4WayFitfS2fX_FGtv1s56RmLB9rx7cfwuFTZjzrKoY,14133
3
+ streamlit_octostar_utils/api_crafter/celery.py,sha256=bQq8P95j0XDWqx6Hdnm96PJL8kcp9ZcSKjveZUCQTVk,29874
4
+ streamlit_octostar_utils/api_crafter/fastapi.py,sha256=2bktT5Mwjs9XixWcOqUKMoLM_cgKl-cqZDUa2Imf4xA,14357
5
5
  streamlit_octostar_utils/api_crafter/nifi.py,sha256=fQ5k9eZl2oSQZ2BexZYwKUiO05-FryUi7wnCd_56P9Y,44375
6
6
  streamlit_octostar_utils/api_crafter/parser/__init__.py,sha256=YeYWF6sdQiCFV_RKNW2t9Vs6KJExE2pbXxWTe_DOayY,107
7
7
  streamlit_octostar_utils/api_crafter/parser/combine_fields.py,sha256=ddc44xkajw8MU0peAX_263DL7rPXbTKbHUjpOhRgvyU,8790
8
- streamlit_octostar_utils/api_crafter/parser/entities_parser.py,sha256=7mUxwcOcaIhDx3GnJ42p5L0PUfAiEvE_fkopNIujlL8,30067
8
+ streamlit_octostar_utils/api_crafter/parser/entities_parser.py,sha256=Z740IViQ8WX3xBzgWzsO6JHUps6GyNLJE8nlpt3KTzc,31418
9
9
  streamlit_octostar_utils/api_crafter/parser/generics.py,sha256=GefvTUWkqsICS_TdXA2p73_Uzh6041g88mWql3Fr9cY,1861
10
10
  streamlit_octostar_utils/api_crafter/parser/info.py,sha256=L2cdtsmfIdFSkAnIXhGhQZG6YMZRtY1GgLXn-847avA,649
11
11
  streamlit_octostar_utils/api_crafter/parser/linkchart_functions.py,sha256=WfHl-EfH4SWjpk8civS7HL11eIl4SAV5Dtwe8mTidrc,7163
@@ -37,7 +37,7 @@ streamlit_octostar_utils/threading/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzp
37
37
  streamlit_octostar_utils/threading/async_task_manager.py,sha256=q7N6YZwUvIYMzkSHmsJNheNVCv93c03H6Hyg9uH8pvk,4747
38
38
  streamlit_octostar_utils/threading/session_callback_manager.py,sha256=LvZVP4g6tvKtYmI13f2j1sX_7hm61Groqp5xJine9_k,3973
39
39
  streamlit_octostar_utils/threading/session_state_hot_swapper.py,sha256=6eeCQI6A42hp4DmW2NQw2rbeR-k9N8DhfBKQdN_fbLU,811
40
- streamlit_octostar_utils-0.1.7a8.dist-info/LICENSE,sha256=dkwVPyV03fPHHtERnF6RnvRXcll__tud9gWca1RcgnQ,1073
41
- streamlit_octostar_utils-0.1.7a8.dist-info/METADATA,sha256=Qu54yUOzUMNjTN-JEZLeQa59Ibb2UNLZ1j3bj5XPT84,2267
42
- streamlit_octostar_utils-0.1.7a8.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
43
- streamlit_octostar_utils-0.1.7a8.dist-info/RECORD,,
40
+ streamlit_octostar_utils-0.1.7a10.dist-info/LICENSE,sha256=dkwVPyV03fPHHtERnF6RnvRXcll__tud9gWca1RcgnQ,1073
41
+ streamlit_octostar_utils-0.1.7a10.dist-info/METADATA,sha256=s86wH6OAhUfZBkiM2dIFUcw1x7g3COOUjBkWSYnmJGc,2268
42
+ streamlit_octostar_utils-0.1.7a10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
43
+ streamlit_octostar_utils-0.1.7a10.dist-info/RECORD,,