@typespec/http-client-python 0.37.2 → 0.38.0

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.
@@ -33,7 +33,8 @@ from typing import (
33
33
 
34
34
  from typing_extensions import Self
35
35
 
36
- from {{ code_model.core_library }}.rest import AsyncHttpResponse, HttpResponse
36
+ from {{ code_model.core_library }}.exceptions import StreamClosedError, StreamConsumedError
37
+ from {{ code_model.core_library }}.rest import AsyncHttpResponse, HttpRequest, HttpResponse
37
38
 
38
39
  DecodedType = TypeVar("DecodedType")
39
40
  ReturnType_co = TypeVar("ReturnType_co", covariant=True)
@@ -435,13 +436,56 @@ async def _aiter_sse_lines(iter_bytes: AsyncIterator[bytes]) -> AsyncGenerator[s
435
436
  yield line
436
437
 
437
438
 
439
+ def _read_sse_response(response: HttpResponse) -> None:
440
+ """Read an SSE response body, ignoring responses that are already consumed or closed.
441
+
442
+ :param response: The response to read.
443
+ :type response: HttpResponse
444
+ """
445
+ try:
446
+ response.read()
447
+ except (StreamConsumedError, StreamClosedError):
448
+ pass
449
+
450
+
451
+ async def _read_sse_response_async(response: AsyncHttpResponse) -> None:
452
+ """Read an SSE response body, ignoring responses that are already consumed or closed.
453
+
454
+ :param response: The response to read.
455
+ :type response: AsyncHttpResponse
456
+ """
457
+ try:
458
+ await response.read()
459
+ except (StreamConsumedError, StreamClosedError):
460
+ pass
461
+
462
+
463
+ def _update_sse_request_headers(request: HttpRequest, last_event_id: Optional[str]) -> None:
464
+ """Update the last event ID header for an SSE reconnection request.
465
+
466
+ :param request: The reconnection request to update.
467
+ :type request: HttpRequest
468
+ :param last_event_id: The current value of the SSE last event ID buffer.
469
+ :type last_event_id: str or None
470
+ """
471
+ if last_event_id:
472
+ request.headers["Last-Event-ID"] = last_event_id
473
+ else:
474
+ request.headers.pop("Last-Event-ID", None)
475
+
476
+
438
477
  class _SSEEventBuilder:
439
- """Accumulates SSE field lines and builds :class:`ServerSentEvent` instances."""
478
+ """Accumulates SSE field lines and builds :class:`ServerSentEvent` instances.
440
479
 
441
- def __init__(self) -> None:
480
+ :param last_event_id: The initial value of the SSE last event ID buffer.
481
+ :type last_event_id: str
482
+ """
483
+
484
+ def __init__(self, last_event_id: str = "") -> None:
442
485
  self._data: List[str] = []
443
486
  self._event_type = ""
444
- self._last_id = ""
487
+ self._last_id = last_event_id
488
+ self._pending_last_id = last_event_id
445
489
  self._retry: Optional[int] = None
446
490
 
447
491
  def add_line(self, line: str) -> Optional[ServerSentEvent]:
@@ -469,7 +513,7 @@ class _SSEEventBuilder:
469
513
  self._data.append(value)
470
514
  elif field == "id":
471
515
  if "\x00" not in value:
472
- self._last_id = value
516
+ self._pending_last_id = value
473
517
  elif field == "retry":
474
518
  if value.isascii() and value.isdigit():
475
519
  try:
@@ -482,6 +526,7 @@ class _SSEEventBuilder:
482
526
  return None
483
527
 
484
528
  def _dispatch(self) -> Optional[ServerSentEvent]:
529
+ self._last_id = self._pending_last_id
485
530
  if not self._data:
486
531
  # No data accumulated: reset and dispatch nothing.
487
532
  self._event_type = ""
@@ -496,13 +541,55 @@ class _SSEEventBuilder:
496
541
  self._event_type = ""
497
542
  return event
498
543
 
544
+ @property
545
+ def last_event_id(self) -> str:
546
+ """Return the current value of the last event ID buffer.
547
+
548
+ :return: The current value of the last event ID buffer.
549
+ :rtype: str
550
+ """
551
+ return self._last_id
552
+
553
+ @property
554
+ def retry(self) -> Optional[int]:
555
+ """Return the most recently received valid reconnection time.
556
+
557
+ :return: The reconnection time in milliseconds, if one was provided.
558
+ :rtype: int or None
559
+ """
560
+ return self._retry
561
+
499
562
 
500
563
  class SSEDecoder:
501
564
  """Decoder for Server-Sent Events (SSE).
502
565
 
503
566
  https://html.spec.whatwg.org/multipage/server-sent-events.html
567
+
568
+ :keyword last_event_id: The initial value of the SSE last event ID buffer.
569
+ :paramtype last_event_id: str or None
504
570
  """
505
571
 
572
+ def __init__(self, *, last_event_id: Optional[str] = None) -> None:
573
+ self._builder = _SSEEventBuilder(last_event_id or "")
574
+
575
+ @property
576
+ def last_event_id(self) -> str:
577
+ """Return the current value of the last event ID buffer.
578
+
579
+ :return: The current value of the last event ID buffer.
580
+ :rtype: str
581
+ """
582
+ return self._builder.last_event_id
583
+
584
+ @property
585
+ def retry(self) -> Optional[int]:
586
+ """Return the most recently received valid reconnection time.
587
+
588
+ :return: The reconnection time in milliseconds, if one was provided.
589
+ :rtype: int or None
590
+ """
591
+ return self._builder.retry
592
+
506
593
  def iter_events(self, iter_bytes: Iterator[bytes]) -> Iterator[ServerSentEvent]:
507
594
  """Iterate over SSE events from a byte iterator.
508
595
 
@@ -511,9 +598,8 @@ class SSEDecoder:
511
598
  :rtype: Iterator[ServerSentEvent]
512
599
  :return: An iterator of server-sent events.
513
600
  """
514
- builder = _SSEEventBuilder()
515
601
  for line in _iter_sse_lines(iter_bytes):
516
- event = builder.add_line(line)
602
+ event = self._builder.add_line(line)
517
603
  if event is not None:
518
604
  yield event
519
605
 
@@ -522,8 +608,32 @@ class AsyncSSEDecoder:
522
608
  """Asynchronous decoder for Server-Sent Events (SSE).
523
609
 
524
610
  https://html.spec.whatwg.org/multipage/server-sent-events.html
611
+
612
+ :keyword last_event_id: The initial value of the SSE last event ID buffer.
613
+ :paramtype last_event_id: str or None
525
614
  """
526
615
 
616
+ def __init__(self, *, last_event_id: Optional[str] = None) -> None:
617
+ self._builder = _SSEEventBuilder(last_event_id or "")
618
+
619
+ @property
620
+ def last_event_id(self) -> str:
621
+ """Return the current value of the last event ID buffer.
622
+
623
+ :return: The current value of the last event ID buffer.
624
+ :rtype: str
625
+ """
626
+ return self._builder.last_event_id
627
+
628
+ @property
629
+ def retry(self) -> Optional[int]:
630
+ """Return the most recently received valid reconnection time.
631
+
632
+ :return: The reconnection time in milliseconds, if one was provided.
633
+ :rtype: int or None
634
+ """
635
+ return self._builder.retry
636
+
527
637
  # pylint: disable=invalid-overridden-method
528
638
  async def aiter_events(self, iter_bytes: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]:
529
639
  """Asynchronously iterate over SSE events from a byte iterator.
@@ -533,10 +643,9 @@ class AsyncSSEDecoder:
533
643
  :rtype: AsyncIterator[ServerSentEvent]
534
644
  :return: An asynchronous iterator of server-sent events.
535
645
  """
536
- builder = _SSEEventBuilder()
537
646
  async with aclosing(_aiter_sse_lines(iter_bytes)) as lines:
538
647
  async for line in lines:
539
- event = builder.add_line(line)
648
+ event = self._builder.add_line(line)
540
649
  if event is not None:
541
650
  yield event
542
651
 
@@ -563,6 +672,14 @@ class Stream(Iterator[ReturnType_co]):
563
672
  :keyword terminal_event_predicate: Optional predicate that identifies a payload-bearing
564
673
  terminal event. The event is yielded before iteration stops.
565
674
  :paramtype terminal_event_predicate: Callable[[Any], bool] or None
675
+ :keyword last_event_id: Optional event ID from which this stream is resuming.
676
+ :paramtype last_event_id: str or None
677
+ :keyword reconnect_callback: Optional callback used to re-establish the underlying response
678
+ when the stream disconnects before a terminal event is seen. Reconnection uses a
679
+ three-second delay unless the server provides an SSE ``retry`` value. The callback is
680
+ called with the last-seen SSE event ID (or ``None``) and the reconnect delay in seconds,
681
+ and must return a new response.
682
+ :paramtype reconnect_callback: Callable[[str or None, float], ~{{ code_model.core_library }}.rest.HttpResponse] or None
566
683
  """
567
684
 
568
685
  def __init__(
@@ -574,17 +691,26 @@ class Stream(Iterator[ReturnType_co]):
574
691
  terminal_event: Optional[str] = None,
575
692
  terminal_event_names: Optional[Sequence[str]] = None,
576
693
  terminal_event_predicate: Optional[Callable[[DecodedType], bool]] = None,
694
+ last_event_id: Optional[str] = None,
695
+ reconnect_callback: Optional[Callable[[Optional[str], float], HttpResponse]] = None,
577
696
  ) -> None:
578
697
  self._response = response
579
698
  content_type = response.headers.get("Content-Type", "").split(";", 1)[0].strip().lower()
580
699
  self._decoder: StreamDecoder[Any] = (
581
- decoder if decoder is not None else (SSEDecoder() if content_type == "text/event-stream" else JSONLDecoder())
700
+ decoder
701
+ if decoder is not None
702
+ else (
703
+ SSEDecoder(last_event_id=last_event_id)
704
+ if content_type == "text/event-stream"
705
+ else JSONLDecoder()
706
+ )
582
707
  )
583
708
  self._deserialization_callback = deserialization_callback
584
709
  self._terminal_event = terminal_event
585
710
  self._terminal_event_names = frozenset(terminal_event_names or ())
586
711
  self._terminal_event_predicate = terminal_event_predicate
587
- self._last_event_id: Optional[str] = None
712
+ self._reconnect_callback = reconnect_callback
713
+ self._last_event_id = last_event_id
588
714
  self._retry: Optional[int] = None
589
715
  self._iterator = self._iter_results()
590
716
 
@@ -605,26 +731,46 @@ class Stream(Iterator[ReturnType_co]):
605
731
  return self
606
732
 
607
733
  def _iter_results(self) -> Generator[ReturnType_co, None, None]:
734
+ terminal = False
608
735
  try:
609
- for event in self._decoder.iter_events(self._response.iter_bytes()):
610
- event_id = getattr(event, "id", None)
611
- if event_id is not None:
612
- self._last_event_id = event_id
613
- event_retry = getattr(event, "retry", None)
614
- if event_retry is not None:
615
- self._retry = event_retry
616
- if self._terminal_event is not None and getattr(event, "data", None) == self._terminal_event:
736
+ while True:
737
+ if getattr(self._response, "status_code", None) == 204:
617
738
  break
618
- result = self._deserialization_callback(self._response, event)
619
- yield result
620
- if (
621
- self._terminal_event_names
622
- and getattr(event, "event", None) in self._terminal_event_names
623
- ) or (
624
- self._terminal_event_predicate is not None
625
- and self._terminal_event_predicate(event)
626
- ):
739
+ for event in self._decoder.iter_events(self._response.iter_bytes()):
740
+ event_id = getattr(event, "id", None)
741
+ if event_id is not None:
742
+ self._last_event_id = event_id
743
+ event_retry = getattr(event, "retry", None)
744
+ if event_retry is not None:
745
+ self._retry = event_retry
746
+ if self._terminal_event is not None and getattr(event, "data", None) == self._terminal_event:
747
+ terminal = True
748
+ break
749
+ result = self._deserialization_callback(self._response, cast(Any, event))
750
+ yield result
751
+ if (
752
+ self._terminal_event_names
753
+ and getattr(event, "event", None) in self._terminal_event_names
754
+ ) or (
755
+ self._terminal_event_predicate is not None
756
+ and self._terminal_event_predicate(cast(Any, event))
757
+ ):
758
+ terminal = True
759
+ break
760
+ if terminal or self._reconnect_callback is None:
627
761
  break
762
+ if isinstance(self._decoder, SSEDecoder):
763
+ self._last_event_id = self._decoder.last_event_id
764
+ if self._decoder.retry is not None:
765
+ self._retry = self._decoder.retry
766
+ self._response.close()
767
+ reconnect_delay = (self._retry if self._retry is not None else 3000) / 1000
768
+ self._response = self._reconnect_callback(self._last_event_id, reconnect_delay)
769
+ self._decoder = (
770
+ SSEDecoder(last_event_id=self._last_event_id)
771
+ if isinstance(self._decoder, SSEDecoder)
772
+ else type(self._decoder)()
773
+ )
628
774
  finally:
629
775
  self._response.close()
630
776
 
@@ -668,6 +814,14 @@ class AsyncStream(AsyncIterator[ReturnType_co]):
668
814
  :keyword terminal_event_predicate: Optional predicate that identifies a payload-bearing
669
815
  terminal event. The event is yielded before iteration stops.
670
816
  :paramtype terminal_event_predicate: Callable[[Any], bool] or None
817
+ :keyword last_event_id: Optional event ID from which this stream is resuming.
818
+ :paramtype last_event_id: str or None
819
+ :keyword reconnect_callback: Optional callback used to re-establish the underlying response
820
+ when the stream disconnects before a terminal event is seen. Reconnection uses a
821
+ three-second delay unless the server provides an SSE ``retry`` value. The callback is
822
+ called with the last-seen SSE event ID (or ``None``) and the reconnect delay in seconds,
823
+ and must resolve to a new response.
824
+ :paramtype reconnect_callback: Callable[[str or None, float], Any] or None
671
825
  """
672
826
 
673
827
  def __init__(
@@ -679,19 +833,26 @@ class AsyncStream(AsyncIterator[ReturnType_co]):
679
833
  terminal_event: Optional[str] = None,
680
834
  terminal_event_names: Optional[Sequence[str]] = None,
681
835
  terminal_event_predicate: Optional[Callable[[DecodedType], bool]] = None,
836
+ last_event_id: Optional[str] = None,
837
+ reconnect_callback: Optional[Callable[[Optional[str], float], Any]] = None,
682
838
  ) -> None:
683
839
  self._response = response
684
840
  content_type = response.headers.get("Content-Type", "").split(";", 1)[0].strip().lower()
685
841
  self._decoder: AsyncStreamDecoder[Any] = (
686
842
  decoder
687
843
  if decoder is not None
688
- else (AsyncSSEDecoder() if content_type == "text/event-stream" else AsyncJSONLDecoder())
844
+ else (
845
+ AsyncSSEDecoder(last_event_id=last_event_id)
846
+ if content_type == "text/event-stream"
847
+ else AsyncJSONLDecoder()
848
+ )
689
849
  )
690
850
  self._deserialization_callback = deserialization_callback
691
851
  self._terminal_event = terminal_event
692
852
  self._terminal_event_names = frozenset(terminal_event_names or ())
693
853
  self._terminal_event_predicate = terminal_event_predicate
694
- self._last_event_id: Optional[str] = None
854
+ self._reconnect_callback = reconnect_callback
855
+ self._last_event_id = last_event_id
695
856
  self._retry: Optional[int] = None
696
857
  self._iterator = self._iter_results()
697
858
 
@@ -712,34 +873,54 @@ class AsyncStream(AsyncIterator[ReturnType_co]):
712
873
  return self
713
874
 
714
875
  async def _iter_results(self) -> AsyncGenerator[ReturnType_co, None]:
715
- events = self._decoder.aiter_events(self._response.iter_bytes())
876
+ terminal = False
716
877
  try:
717
- async for event in events:
718
- event_id = getattr(event, "id", None)
719
- if event_id is not None:
720
- self._last_event_id = event_id
721
- event_retry = getattr(event, "retry", None)
722
- if event_retry is not None:
723
- self._retry = event_retry
724
- if self._terminal_event is not None and getattr(event, "data", None) == self._terminal_event:
878
+ while True:
879
+ if getattr(self._response, "status_code", None) == 204:
725
880
  break
726
- result = self._deserialization_callback(self._response, event)
727
- yield result
728
- if (
729
- self._terminal_event_names
730
- and getattr(event, "event", None) in self._terminal_event_names
731
- ) or (
732
- self._terminal_event_predicate is not None
733
- and self._terminal_event_predicate(event)
734
- ):
881
+ events = self._decoder.aiter_events(self._response.iter_bytes())
882
+ try:
883
+ async for event in events:
884
+ event_id = getattr(event, "id", None)
885
+ if event_id is not None:
886
+ self._last_event_id = event_id
887
+ event_retry = getattr(event, "retry", None)
888
+ if event_retry is not None:
889
+ self._retry = event_retry
890
+ if self._terminal_event is not None and getattr(event, "data", None) == self._terminal_event:
891
+ terminal = True
892
+ break
893
+ result = self._deserialization_callback(self._response, cast(Any, event))
894
+ yield result
895
+ if (
896
+ self._terminal_event_names
897
+ and getattr(event, "event", None) in self._terminal_event_names
898
+ ) or (
899
+ self._terminal_event_predicate is not None
900
+ and self._terminal_event_predicate(cast(Any, event))
901
+ ):
902
+ terminal = True
903
+ break
904
+ finally:
905
+ aclose = getattr(events, "aclose", None)
906
+ if aclose is not None:
907
+ await aclose()
908
+ if terminal or self._reconnect_callback is None:
735
909
  break
736
- finally:
737
- try:
738
- aclose = getattr(events, "aclose", None)
739
- if aclose is not None:
740
- await aclose()
741
- finally:
910
+ if isinstance(self._decoder, AsyncSSEDecoder):
911
+ self._last_event_id = self._decoder.last_event_id
912
+ if self._decoder.retry is not None:
913
+ self._retry = self._decoder.retry
742
914
  await self._response.close()
915
+ reconnect_delay = (self._retry if self._retry is not None else 3000) / 1000
916
+ self._response = await self._reconnect_callback(self._last_event_id, reconnect_delay)
917
+ self._decoder = (
918
+ AsyncSSEDecoder(last_event_id=self._last_event_id)
919
+ if isinstance(self._decoder, AsyncSSEDecoder)
920
+ else type(self._decoder)()
921
+ )
922
+ finally:
923
+ await self._response.close()
743
924
 
744
925
  async def __aexit__(
745
926
  self,
@@ -4,6 +4,6 @@
4
4
  {% endif %}
5
5
 
6
6
  {{ imports }}
7
- {% for nu in code_model.named_unions %}
8
- {{nu.name}} = {{nu.type_definition()}}
7
+ {% for nu in named_unions %}
8
+ {{nu.name}}: TypeAlias = {{nu.type_definition()}}
9
9
  {% endfor %}
@@ -54,13 +54,14 @@ def add_overload(yaml_data: dict[str, Any], body_type: dict[str, Any], for_flatt
54
54
  if yaml_data.get("initialOperation"):
55
55
  overload["initialOperation"] = yaml_data["initialOperation"]
56
56
 
57
+ # Reattach shared type objects before filtering parameters so positional
58
+ # alignment with the original operation is preserved.
59
+ for overload_p, original_p in zip(overload["parameters"], yaml_data["parameters"]):
60
+ overload_p["type"] = original_p["type"]
57
61
  if for_flatten_params:
58
62
  overload["bodyParameter"]["flattened"] = True
59
63
  else:
60
64
  overload["parameters"] = [p for p in overload["parameters"] if not p.get("inFlattenedBody")]
61
- # for yaml sync, we need to make sure all of the responses, parameters, and exceptions' types have the same yaml id
62
- for overload_p, original_p in zip(overload["parameters"], yaml_data["parameters"]):
63
- overload_p["type"] = original_p["type"]
64
65
  update_overload_section(overload, yaml_data, "responses")
65
66
  update_overload_section(overload, yaml_data, "exceptions")
66
67
 
@@ -95,12 +96,14 @@ def add_overloads_for_body_param(yaml_data: dict[str, Any], skip_single_body_jso
95
96
  raw-JSON overload is kept, matching pre-TypedDict behavior).
96
97
  """
97
98
  body_parameter = yaml_data["bodyParameter"]
99
+ body_types = body_parameter["type"].get("types", [])
98
100
  if not (
99
101
  body_parameter["type"]["type"] == "combined"
100
- and len(yaml_data["bodyParameter"]["type"]["types"]) > len(yaml_data["overloads"])
102
+ and len(body_types) > 1
103
+ and len(body_types) > len(yaml_data["overloads"])
101
104
  ):
102
105
  return
103
- for body_type in body_parameter["type"]["types"]:
106
+ for body_type in body_types:
104
107
  if any(o for o in yaml_data["overloads"] if id(o["bodyParameter"]["type"]) == id(body_type)):
105
108
  continue
106
109
  if body_type.get("type") == "model" and body_type.get("base") == "json":
@@ -262,9 +265,6 @@ def _process_operation_etag_headers(
262
265
  if_match_candidates: list[dict[str, Any]] = []
263
266
  if_none_match_candidates: list[dict[str, Any]] = []
264
267
  for p in operation["parameters"]:
265
- wire_name_lower = get_wire_name_lower(p)
266
- if p["location"] == "header" and wire_name_lower == "client-request-id":
267
- client["requestIdHeaderName"] = wire_name_lower
268
268
  if version_tolerant and p["location"] == "header":
269
269
  role = _get_etag_role(p)
270
270
  if role == "ifMatch":
@@ -273,7 +273,6 @@ def _process_operation_etag_headers(
273
273
  if_none_match_candidates.append(p)
274
274
 
275
275
  property_if_match, property_if_none_match = _resolve_etag_pair(if_match_candidates, if_none_match_candidates)
276
-
277
276
  if property_if_match and property_if_none_match:
278
277
  etag_params = {id(property_if_match), id(property_if_none_match)}
279
278
  operation["parameters"] = [item for item in operation["parameters"] if id(item) not in etag_params] + [
@@ -284,6 +283,21 @@ def _process_operation_etag_headers(
284
283
  client["hasEtag"] = True
285
284
 
286
285
 
286
+ def _process_operation_group_etag_headers(
287
+ operation_groups: list[dict[str, Any]],
288
+ client: dict[str, Any],
289
+ version_tolerant: bool,
290
+ ) -> None:
291
+ for operation_group in operation_groups:
292
+ for operation in operation_group.get("operations", []):
293
+ _process_operation_etag_headers(operation, client, version_tolerant)
294
+ _process_operation_group_etag_headers(
295
+ operation_group.get("operationGroups", []),
296
+ client,
297
+ version_tolerant,
298
+ )
299
+
300
+
287
301
  def headers_convert(yaml_data: dict[str, Any], replace_data: Any) -> None:
288
302
  if isinstance(replace_data, dict):
289
303
  for k, v in replace_data.items():
@@ -605,9 +619,16 @@ class PreProcessPlugin(YamlUpdatePlugin):
605
619
  if prop_name.endswith("Client"):
606
620
  prop_name = prop_name[: len(prop_name) - len("Client")]
607
621
  yaml_data["builderPadName"] = to_snake_case(prop_name)
608
- for og in yaml_data.get("operationGroups", []):
609
- for o in og["operations"]:
610
- _process_operation_etag_headers(o, yaml_data, self.version_tolerant)
622
+ for operation_group in yaml_data.get("operationGroups", []):
623
+ for operation in operation_group.get("operations", []):
624
+ for parameter in operation["parameters"]:
625
+ if parameter["location"] == "header" and get_wire_name_lower(parameter) == "client-request-id":
626
+ yaml_data["requestIdHeaderName"] = "client-request-id"
627
+ _process_operation_group_etag_headers(
628
+ yaml_data.get("operationGroups", []),
629
+ yaml_data,
630
+ self.version_tolerant,
631
+ )
611
632
 
612
633
  # add client signature cloud_setting for arm
613
634
  if self.azure_arm and yaml_data["parameters"]:
@@ -267,6 +267,11 @@ class Response(BaseModel):
267
267
  file_import.add_submodule_import(relative_path, stream_class, ImportType.LOCAL)
268
268
  if self.streaming_kind == "sse":
269
269
  file_import.add_import("json", ImportType.STDLIB)
270
+ read_response_helper = (
271
+ "_read_sse_response_async" if kwargs.get("async_mode", False) else "_read_sse_response"
272
+ )
273
+ file_import.add_submodule_import(relative_path, read_response_helper, ImportType.LOCAL)
274
+ file_import.add_submodule_import(relative_path, "_update_sse_request_headers", ImportType.LOCAL)
270
275
  for event in self.streaming_events:
271
276
  file_import.merge(event.payload_type.imports(**kwargs))
272
277
  return file_import