@@ -438,8 +438,7 @@ def stream_output_sync(self, *, debounce_by: float | None = 0.1) -> Iterator[Out
438438 Returns:
439439 An iterable of the response data.
440440 """
441- async_stream = self .stream_output (debounce_by = debounce_by )
442- yield from _blocking_async_iterator (async_stream )
441+ return _utils .sync_async_iterator (self .stream_output (debounce_by = debounce_by ))
443442
444443 async def stream_text (self , * , delta : bool = False , debounce_by : float | None = 0.1 ) -> AsyncIterator [str ]:
445444 """Stream the text result as an async iterable.
@@ -485,8 +484,7 @@ def stream_text_sync(self, *, delta: bool = False, debounce_by: float | None = 0
485484 Debouncing is particularly important for long structured responses to reduce the overhead of
486485 performing validation as each token is received.
487486 """
488- async_stream = self .stream_text (delta = delta , debounce_by = debounce_by )
489- yield from _blocking_async_iterator (async_stream )
487+ return _utils .sync_async_iterator (self .stream_text (delta = delta , debounce_by = debounce_by ))
490488
491489 @deprecated ('`StreamedRunResult.stream_structured` is deprecated, use `stream_responses` instead.' )
492490 async def stream_structured (
@@ -539,8 +537,7 @@ def stream_responses_sync(
539537 Returns:
540538 An iterable of the structured response message and whether that is the last message.
541539 """
542- async_stream = self .stream_responses (debounce_by = debounce_by )
543- yield from _blocking_async_iterator (async_stream )
540+ return _utils .sync_async_iterator (self .stream_responses (debounce_by = debounce_by ))
544541
545542 async def get_output (self ) -> OutputDataT :
546543 """Stream the whole response, validate and return it."""
@@ -614,6 +611,18 @@ async def validate_response_output(
614611 else :
615612 raise ValueError ('No stream response or run result provided' ) # pragma: no cover
616613
614+ def validate_response_output_sync (
615+ self , message : _messages .ModelResponse , * , allow_partial : bool = False
616+ ) -> OutputDataT :
617+ """Validate a structured result message.
618+
619+ This is a convenience method that wraps [`validate_response_output()`][pydantic_ai.result.StreamedRunResult.validate_response_output] with `loop.run_until_complete(...)`.
620+ You therefore can't use this method inside async code or if there's an active event loop.
621+ """
622+ return _utils .get_event_loop ().run_until_complete (
623+ self .validate_response_output (message , allow_partial = allow_partial )
624+ )
625+
617626 async def _marked_completed (self , message : _messages .ModelResponse | None = None ) -> None :
618627 self .is_complete = True
619628 if message is not None :
@@ -638,15 +647,6 @@ class FinalResult(Generic[OutputDataT]):
638647 __repr__ = _utils .dataclasses_no_defaults_repr
639648
640649
641- def _blocking_async_iterator (async_iter : AsyncIterator [T ]) -> Iterator [T ]:
642- loop = _utils .get_event_loop ()
643- while True :
644- try :
645- yield loop .run_until_complete (async_iter .__anext__ ())
646- except StopAsyncIteration :
647- break
648-
649-
650650def _get_usage_checking_stream_response (
651651 stream_response : models .StreamedResponse ,
652652 limits : UsageLimits | None ,
0 commit comments