nebu 0.1.103__py3-none-any.whl → 0.1.104__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.
@@ -609,47 +609,66 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
609
609
 
610
610
  logger.debug(f">> Raw payload: {raw_payload}")
611
611
 
612
- kind = raw_payload.get("kind", "")
613
- msg_id = raw_payload.get("id", "")
614
- content_raw = raw_payload.get("content", {})
615
- created_at_str = raw_payload.get("created_at") # Get as string or None
616
- # Attempt to parse created_at, fallback to now()
612
+ # --- Extract fields from the *inner* message content for HealthCheck and regular processing ---
613
+ # The actual message content is inside raw_payload[\"content\"]
614
+ inner_content_data = raw_payload.get("content", {})
615
+ if not isinstance(inner_content_data, dict):
616
+ # If content is not a dict (e.g. already a primitive from a non-Message processor)
617
+ # we can't reliably get 'kind' or other fields from it.
618
+ # This case is more relevant for non-StreamMessage processors.
619
+ # For HealthChecks, we expect a structured 'content'.
620
+ logger.warning(
621
+ f"Received non-dict inner_content_data: {inner_content_data}. HealthCheck might be missed if applicable."
622
+ )
623
+ inner_kind = "" # Default to empty string
624
+ inner_msg_id = "" # Default to empty string
625
+ actual_content_to_process = inner_content_data # Use it as is
626
+ inner_created_at_str = None
627
+ 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")
633
+
634
+ # Attempt to parse inner_created_at, fallback to now()
617
635
  try:
618
- created_at = (
619
- datetime.fromisoformat(created_at_str)
620
- if created_at_str
621
- and isinstance(created_at_str, str) # Check type explicitly
636
+ inner_created_at = (
637
+ datetime.fromisoformat(inner_created_at_str)
638
+ if inner_created_at_str and isinstance(inner_created_at_str, str)
622
639
  else datetime.now(timezone.utc)
623
640
  )
624
641
  except ValueError:
625
- created_at = datetime.now(timezone.utc)
642
+ inner_created_at = datetime.now(timezone.utc)
626
643
 
644
+ # These are from the outer envelope, might be useful for routing/meta
627
645
  return_stream = raw_payload.get("return_stream")
628
646
  user_id = raw_payload.get("user_id")
629
- orgs = raw_payload.get("organizations")
630
- handle = raw_payload.get("handle")
631
- adapter = raw_payload.get("adapter")
632
- api_key = raw_payload.get("api_key")
647
+ orgs = raw_payload.get("organizations") # from outer
648
+ handle = raw_payload.get("handle") # from outer
649
+ adapter = raw_payload.get("adapter") # from outer
650
+ api_key = raw_payload.get("api_key") # from outer
633
651
  logger.debug(f">> Extracted API key length: {len(api_key) if api_key else 0}")
634
652
 
635
- # --- Health Check Logic (Keep as is) ---
636
- if kind == "HealthCheck":
637
- logger.info(f"Received HealthCheck message {message_id}")
653
+ # --- Health Check Logic ---
654
+ # Use inner_kind for health check
655
+ if inner_kind == "HealthCheck":
656
+ logger.info(
657
+ f"Received HealthCheck message {message_id} (inner_id: {inner_msg_id})"
658
+ )
638
659
  health_response = {
639
- "kind": "StreamResponseMessage", # Respond with a standard message kind
640
- "id": message_id,
641
- "content": {"status": "healthy", "checked_message_id": msg_id},
660
+ "kind": "StreamResponseMessage",
661
+ "id": message_id, # Use outer message_id for response ID
662
+ "content": {"status": "healthy", "checked_message_id": inner_msg_id},
642
663
  "status": "success",
643
- "created_at": datetime.now().isoformat(),
644
- "user_id": user_id, # Include user_id if available
664
+ "created_at": datetime.now(timezone.utc).isoformat(),
665
+ "user_id": user_id,
645
666
  }
646
667
  if return_stream:
647
- # Assert type again closer to usage for type checker clarity
648
668
  assert isinstance(return_stream, str)
649
669
  r.xadd(return_stream, {"data": json.dumps(health_response)})
650
670
  logger.info(f"Sent health check response to {return_stream}")
651
671
 
652
- # Assert types again closer to usage for type checker clarity
653
672
  assert isinstance(REDIS_STREAM, str)
654
673
  assert isinstance(REDIS_CONSUMER_GROUP, str)
655
674
  r.xack(REDIS_STREAM, REDIS_CONSUMER_GROUP, message_id)
@@ -657,16 +676,21 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
657
676
  return # Exit early for health checks
658
677
  # --- End Health Check Logic ---
659
678
 
660
- # Parse content if it's a string (e.g., double-encoded JSON)
661
- if isinstance(content_raw, str):
679
+ # For non-HealthCheck messages, the content to be processed by user function
680
+ # is `actual_content_to_process`
681
+ # The `kind` and `id` for the Message object should be from `inner_content_data`
682
+
683
+ # Parse actual_content_to_process if it's a string (e.g., double-encoded JSON)
684
+ # This might be redundant if actual_content_to_process is already a dict from inner_content_data.get("content")
685
+ if isinstance(actual_content_to_process, str):
662
686
  try:
663
- content = json.loads(content_raw)
687
+ content_for_validation = json.loads(actual_content_to_process)
664
688
  except json.JSONDecodeError:
665
- content = content_raw # Keep as string if not valid JSON
689
+ content_for_validation = (
690
+ actual_content_to_process # Keep as string if not valid JSON
691
+ )
666
692
  else:
667
- content = content_raw
668
-
669
- # print(f"Content: {content}")
693
+ content_for_validation = actual_content_to_process
670
694
 
671
695
  # --- Construct Input Object using Imported Types ---
672
696
  input_obj: Any = None
@@ -712,13 +736,15 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
712
736
 
713
737
  if content_model_class:
714
738
  try:
715
- content_model = content_model_class.model_validate(content)
739
+ content_model = content_model_class.model_validate(
740
+ content_for_validation
741
+ )
716
742
  # print(f"Validated content model: {content_model}")
717
743
  input_obj = message_class(
718
- kind=kind,
719
- id=msg_id,
744
+ kind=inner_kind,
745
+ id=inner_msg_id,
720
746
  content=content_model,
721
- created_at=int(created_at.timestamp()),
747
+ created_at=int(inner_created_at.timestamp()),
722
748
  return_stream=return_stream,
723
749
  user_id=user_id,
724
750
  orgs=orgs,
@@ -732,10 +758,10 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
732
758
  )
733
759
  # Fallback to raw content in Message
734
760
  input_obj = message_class(
735
- kind=kind,
736
- id=msg_id,
737
- content=cast(Any, content),
738
- created_at=int(created_at.timestamp()),
761
+ kind=inner_kind,
762
+ id=inner_msg_id,
763
+ content=cast(Any, content_for_validation),
764
+ created_at=int(inner_created_at.timestamp()),
739
765
  return_stream=return_stream,
740
766
  user_id=user_id,
741
767
  orgs=orgs,
@@ -746,10 +772,10 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
746
772
  else:
747
773
  # No content type name or class found, use raw content
748
774
  input_obj = message_class(
749
- kind=kind,
750
- id=msg_id,
751
- content=cast(Any, content),
752
- created_at=int(created_at.timestamp()),
775
+ kind=inner_kind,
776
+ id=inner_msg_id,
777
+ content=cast(Any, content_for_validation),
778
+ created_at=int(inner_created_at.timestamp()),
753
779
  return_stream=return_stream,
754
780
  user_id=user_id,
755
781
  orgs=orgs,
@@ -776,21 +802,23 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
776
802
  logger.warning(
777
803
  f"Warning: Input type class '{param_type_name}' not found. Passing raw content."
778
804
  )
779
- input_obj = content
805
+ input_obj = content_for_validation
780
806
  else:
781
807
  logger.debug(f"Found input model class: {input_type_class}")
782
- input_obj = input_type_class.model_validate(content)
808
+ input_obj = input_type_class.model_validate(
809
+ content_for_validation
810
+ )
783
811
  logger.debug(f"Validated input model: {input_obj}")
784
812
  except AttributeError:
785
813
  logger.warning(
786
814
  f"Warning: Input type class '{param_type_name}' not found in imported module."
787
815
  )
788
- input_obj = content
816
+ input_obj = content_for_validation
789
817
  except Exception as e:
790
818
  logger.error(
791
819
  f"Error resolving/validating input type '{param_type_name}': {e}. Passing raw content."
792
820
  )
793
- input_obj = content
821
+ input_obj = content_for_validation
794
822
 
795
823
  except NameError as e:
796
824
  logger.error(
@@ -803,7 +831,7 @@ def process_message(message_id: str, message_data: Dict[str, str]) -> None:
803
831
  raise # Re-raise unexpected errors during input construction
804
832
 
805
833
  # print(f"Input object: {input_obj}") # Reduce verbosity
806
- # logger.debug(f"Input object: {input_obj}") # Could use logger.debug if needed
834
+ logger.debug(f"Input object: {input_obj}") # Could use logger.debug if needed
807
835
 
808
836
  # Execute the function
809
837
  logger.info("Executing function...")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nebu
3
- Version: 0.1.103
3
+ Version: 0.1.104
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=j6iKF_wc8RUNKrFqjB5keUX-Gj9hGZUbmAjEyTm-Oj0,55367
16
+ nebu/processors/consumer.py,sha256=nsh0U1qUoPb2ZgWjT8nIscPLO9RJUzE5xvCGQE93Yic,57289
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.103.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- nebu-0.1.103.dist-info/METADATA,sha256=PSKpznZOgx6Ua0nIdj532s-Qq1F6n91W53CtBWH8sYI,1798
26
- nebu-0.1.103.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
27
- nebu-0.1.103.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
28
- nebu-0.1.103.dist-info/RECORD,,
24
+ nebu-0.1.104.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
+ nebu-0.1.104.dist-info/METADATA,sha256=oBCj3SIGECDB3Dt7yBzlHxvh0-gOfMtaMzutDEmeWA8,1798
26
+ nebu-0.1.104.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
27
+ nebu-0.1.104.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
28
+ nebu-0.1.104.dist-info/RECORD,,
File without changes