nebu 0.1.105__py3-none-any.whl → 0.1.107__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.
@@ -366,6 +366,8 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
366
366
  global target_function, imported_module, local_namespace
367
367
  global execution_mode, r, REDIS_STREAM, REDIS_CONSUMER_GROUP
368
368
 
369
+ print(f">>> Processing message {message_id}")
370
+
369
371
  # --- Subprocess Execution Path ---
370
372
  if execution_mode == "subprocess":
371
373
  logger.info(f"Processing message {message_id} in subprocess...")
@@ -610,8 +612,15 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
610
612
  logger.debug(f">> Raw payload: {raw_payload}")
611
613
 
612
614
  # --- Extract fields from the *inner* message content for HealthCheck and regular processing ---
613
- # The actual message content is inside raw_payload[\"content\"]
615
+ # The actual message content is inside raw_payload["content"]
614
616
  inner_content_data = raw_payload.get("content", {})
617
+
618
+ # Add debug logging for content structure analysis
619
+ logger.debug(f">> inner_content_data type: {type(inner_content_data)}")
620
+ logger.debug(
621
+ f">> inner_content_data keys (if dict): {list(inner_content_data.keys()) if isinstance(inner_content_data, dict) else 'N/A'}"
622
+ )
623
+
615
624
  if not isinstance(inner_content_data, dict):
616
625
  # If content is not a dict (e.g. already a primitive from a non-Message processor)
617
626
  # we can't reliably get 'kind' or other fields from it.
@@ -625,11 +634,44 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
625
634
  actual_content_to_process = inner_content_data # Use it as is
626
635
  inner_created_at_str = None
627
636
  else:
628
- inner_kind = inner_content_data.get("kind", "")
629
- inner_msg_id = inner_content_data.get("id", "")
630
- # The 'content' field of the inner_content_data is what the user function expects
631
- actual_content_to_process = inner_content_data.get("content", {})
632
- inner_created_at_str = inner_content_data.get("created_at")
637
+ # Check if this looks like a nested message structure (has kind/id/content fields)
638
+ # vs direct content data
639
+ has_message_structure = (
640
+ "kind" in inner_content_data
641
+ and "id" in inner_content_data
642
+ and "content" in inner_content_data
643
+ )
644
+
645
+ logger.debug(f">> has_message_structure: {has_message_structure}")
646
+
647
+ if has_message_structure:
648
+ # Nested message structure: extract from inner message
649
+ inner_kind = inner_content_data.get("kind", "")
650
+ inner_msg_id = inner_content_data.get("id", "")
651
+ actual_content_to_process = inner_content_data.get("content", {})
652
+ inner_created_at_str = inner_content_data.get("created_at")
653
+ logger.debug(
654
+ f">> Using nested structure - inner_kind: {inner_kind}, inner_msg_id: {inner_msg_id}"
655
+ )
656
+ logger.debug(
657
+ f">> actual_content_to_process keys: {list(actual_content_to_process.keys())}"
658
+ )
659
+ else:
660
+ # Direct content structure: the content data is directly in inner_content_data
661
+ inner_kind = raw_payload.get("kind", "") # Get kind from outer payload
662
+ inner_msg_id = raw_payload.get("id", "") # Get id from outer payload
663
+ actual_content_to_process = (
664
+ inner_content_data # Use inner_content_data directly
665
+ )
666
+ inner_created_at_str = raw_payload.get(
667
+ "created_at"
668
+ ) # Get created_at from outer payload
669
+ logger.debug(
670
+ f">> Using direct structure - inner_kind: {inner_kind}, inner_msg_id: {inner_msg_id}"
671
+ )
672
+ logger.debug(
673
+ f">> actual_content_to_process keys: {list(actual_content_to_process.keys())}"
674
+ )
633
675
 
634
676
  # Attempt to parse inner_created_at, fallback to now()
635
677
  try:
@@ -685,12 +727,24 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
685
727
  if isinstance(actual_content_to_process, str):
686
728
  try:
687
729
  content_for_validation = json.loads(actual_content_to_process)
730
+ logger.debug(
731
+ f">> Parsed JSON string content_for_validation keys: {list(content_for_validation.keys()) if isinstance(content_for_validation, dict) else 'N/A'}"
732
+ )
688
733
  except json.JSONDecodeError:
689
734
  content_for_validation = (
690
735
  actual_content_to_process # Keep as string if not valid JSON
691
736
  )
737
+ logger.debug(
738
+ f">> Failed to parse JSON, keeping as string: {type(actual_content_to_process)}"
739
+ )
692
740
  else:
693
741
  content_for_validation = actual_content_to_process
742
+ logger.debug(
743
+ f">> Using actual_content_to_process directly: {type(content_for_validation)}"
744
+ )
745
+ logger.debug(
746
+ f">> content_for_validation keys: {list(content_for_validation.keys())}"
747
+ )
694
748
 
695
749
  # --- Construct Input Object using Imported Types ---
696
750
  input_obj: Any = None
@@ -736,9 +790,16 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
736
790
 
737
791
  if content_model_class:
738
792
  try:
793
+ logger.debug(
794
+ f">> Attempting to validate content with {content_model_class.__name__}"
795
+ )
796
+ logger.debug(
797
+ f">> Content being validated: {json.dumps(content_for_validation, indent=2) if isinstance(content_for_validation, dict) else str(content_for_validation)}"
798
+ )
739
799
  content_model = content_model_class.model_validate(
740
800
  content_for_validation
741
801
  )
802
+ logger.debug(f">> Successfully validated content model")
742
803
  # print(f"Validated content model: {content_model}")
743
804
  input_obj = message_class(
744
805
  kind=inner_kind,
@@ -752,10 +813,16 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
752
813
  adapter=adapter,
753
814
  api_key=api_key,
754
815
  )
816
+ logger.debug(
817
+ f">> Successfully created Message object with validated content"
818
+ )
755
819
  except Exception as e:
756
820
  logger.error(
757
821
  f"Error validating/creating content model '{content_type_name}': {e}. Falling back."
758
822
  )
823
+ logger.debug(
824
+ f">> Content validation failed for: {json.dumps(content_for_validation, indent=2) if isinstance(content_for_validation, dict) else str(content_for_validation)}"
825
+ )
759
826
  # Fallback to raw content in Message
760
827
  input_obj = message_class(
761
828
  kind=inner_kind,
@@ -769,8 +836,12 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
769
836
  adapter=adapter,
770
837
  api_key=api_key,
771
838
  )
839
+ logger.debug(
840
+ f">> Created Message object with raw content fallback"
841
+ )
772
842
  else:
773
843
  # No content type name or class found, use raw content
844
+ logger.debug(f">> No content model class found, using raw content")
774
845
  input_obj = message_class(
775
846
  kind=inner_kind,
776
847
  id=inner_msg_id,
@@ -783,6 +854,9 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
783
854
  adapter=adapter,
784
855
  api_key=api_key,
785
856
  )
857
+ logger.debug(
858
+ f">> Created Message object with raw content (no content model class)"
859
+ )
786
860
  else: # Not a stream message, use the function's parameter type
787
861
  param_type_name = (
788
862
  param_type_str # Assume param_type_str holds the class name
@@ -844,7 +918,15 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
844
918
  # Safe logging that avoids __repr__ issues with BaseModel objects
845
919
  try:
846
920
  if hasattr(input_obj, "model_dump"):
847
- logger.debug(f"Input object (BaseModel): {input_obj.model_dump()}")
921
+ try:
922
+ # Use model_dump_json for safer serialization that handles nested objects
923
+ logger.debug(
924
+ f"Input object (BaseModel): {input_obj.model_dump_json()}"
925
+ )
926
+ except Exception as dump_e:
927
+ logger.debug(
928
+ f"Input object: <BaseModel object of type {type(input_obj).__name__}> (model_dump failed: {dump_e})"
929
+ )
848
930
  else:
849
931
  logger.debug(f"Input object: {input_obj}")
850
932
  except Exception as log_e:
@@ -854,15 +936,13 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
854
936
 
855
937
  # Execute the function
856
938
  logger.info("Executing function...")
939
+
940
+ # Add warning about potential print statement issues in user code
941
+ logger.debug(
942
+ ">> About to execute user function - note: print statements in user code may fail if the Message object has validation issues"
943
+ )
944
+
857
945
  result = target_function(input_obj)
858
- # Safe logging that avoids __repr__ issues with BaseModel objects if this debug line is uncommented
859
- # try:
860
- # if hasattr(result, "model_dump"):
861
- # logger.debug(f"Raw Result (BaseModel): {result.model_dump()}")
862
- # else:
863
- # logger.debug(f"Raw Result: {result}")
864
- # except Exception as log_e:
865
- # logger.debug(f"Raw Result: <object of type {type(result).__name__}> (repr failed: {log_e})")
866
946
 
867
947
  result_content = None # Default to None
868
948
  if result is not None: # Only process if there's a result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nebu
3
- Version: 0.1.105
3
+ Version: 0.1.107
4
4
  Summary: A globally distributed container runtime
5
5
  Requires-Python: >=3.10.14
6
6
  Description-Content-Type: text/markdown
@@ -13,7 +13,7 @@ nebu/containers/container.py,sha256=Mrh_gvMsTvDkj3CwpqIPzJ72IMw0gQIg64y548vq0yg,
13
13
  nebu/containers/models.py,sha256=0j6NGy4yto-enRDh_4JH_ZTbHrLdSpuMOqNQPnIrwC4,6815
14
14
  nebu/namespaces/models.py,sha256=EqUOpzhVBhvJw2P92ONDUbIgC31M9jMmcaG5vyOrsWg,497
15
15
  nebu/namespaces/namespace.py,sha256=oeZyGqsIGIrppyjif1ZONsdTmqRgd9oSLFE1BChXTTE,5247
16
- nebu/processors/consumer.py,sha256=v5JsuvEEUUBbe8sKGB2QjHca8FPHMIjq9Ntk32Uf3G4,58674
16
+ nebu/processors/consumer.py,sha256=9WapzBTPuXRunH-vjPerTlGZy__hn_d4m13l1ajebY8,62732
17
17
  nebu/processors/consumer_process_worker.py,sha256=h--eNFKaLbUayxn88mB8oGGdrU2liE1dnwm_TPlewX8,36960
18
18
  nebu/processors/decorate.py,sha256=AfHVCoNbW7RymccF5ewleEL-GlMiqVH1-t9bCmD60rk,58654
19
19
  nebu/processors/default.py,sha256=cy4ETMdbdRGkrvbYec1o60h7mGDlGN5JsuUph0ENtDU,364
@@ -21,8 +21,8 @@ nebu/processors/models.py,sha256=g4B1t6Rgoy-NUEHBLeQc0EENzHXLDlWSio8Muv7cTDU,409
21
21
  nebu/processors/processor.py,sha256=vbafqawdZhh5VRoBE5C5wRR_32iSyzoDTqK7qsNQvaM,19242
22
22
  nebu/redis/models.py,sha256=coPovAcVXnOU1Xh_fpJL4PO3QctgK9nBe5QYoqEcnxg,1230
23
23
  nebu/services/service.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- nebu-0.1.105.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- nebu-0.1.105.dist-info/METADATA,sha256=B9wVIWPowGZHwobFzrRBymh14aUiwL_GAFTNRR80roo,1798
26
- nebu-0.1.105.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
27
- nebu-0.1.105.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
28
- nebu-0.1.105.dist-info/RECORD,,
24
+ nebu-0.1.107.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
+ nebu-0.1.107.dist-info/METADATA,sha256=yd6ycmsMZA8RM6dDaH4EPdoiRyUyG-S6x4j-0FSb168,1798
26
+ nebu-0.1.107.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
27
+ nebu-0.1.107.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
28
+ nebu-0.1.107.dist-info/RECORD,,
File without changes