2
2
from logging import Logger
3
3
from estuary_cdk .incremental_json_processor import Remainder
4
4
from pydantic import BaseModel
5
- from typing import AsyncGenerator , Any , TypeVar , Union , Callable
5
+ from typing import AsyncGenerator , Any , TypeVar
6
6
import abc
7
7
import aiohttp
8
8
import asyncio
25
25
26
26
StreamedObject = TypeVar ("StreamedObject" , bound = BaseModel )
27
27
28
- class Headers (dict [str , Any ]):
29
- pass
30
-
31
-
32
- BodyGeneratorFunction = Callable [[], AsyncGenerator [bytes , None ]]
33
- HeadersAndBodyGenerator = tuple [Headers , BodyGeneratorFunction ]
34
-
35
28
36
29
class HTTPError (RuntimeError ):
37
30
"""
@@ -76,11 +69,9 @@ async def request(
76
69
"""Request a url and return its body as bytes"""
77
70
78
71
chunks : list [bytes ] = []
79
- _ , body_generator = await self ._request_stream (
72
+ async for chunk in self ._request_stream (
80
73
log , url , method , params , json , form , _with_token , headers
81
- )
82
-
83
- async for chunk in body_generator ():
74
+ ):
84
75
chunks .append (chunk )
85
76
86
77
if len (chunks ) == 0 :
@@ -99,26 +90,22 @@ async def request_lines(
99
90
json : dict [str , Any ] | None = None ,
100
91
form : dict [str , Any ] | None = None ,
101
92
delim : bytes = b"\n " ,
102
- headers : dict [str , Any ] = {}
103
- ) -> tuple [Headers , BodyGeneratorFunction ]:
93
+ ) -> AsyncGenerator [bytes , None ]:
104
94
"""Request a url and return its response as streaming lines, as they arrive"""
105
95
106
- headers , body = await self ._request_stream (
107
- log , url , method , params , json , form , True , headers
108
- )
109
-
110
- async def gen () -> AsyncGenerator [bytes , None ]:
111
- buffer = b""
112
- async for chunk in body ():
113
- buffer += chunk
114
- while delim in buffer :
115
- line , buffer = buffer .split (delim , 1 )
116
- yield line
96
+ buffer = b""
97
+ async for chunk in self ._request_stream (
98
+ log , url , method , params , json , form , True
99
+ ):
100
+ buffer += chunk
101
+ while delim in buffer :
102
+ line , buffer = buffer .split (delim , 1 )
103
+ yield line
117
104
118
- if buffer :
119
- yield buffer
105
+ if buffer :
106
+ yield buffer
120
107
121
- return ( headers , gen )
108
+ return
122
109
123
110
async def request_stream (
124
111
self ,
@@ -128,15 +115,13 @@ async def request_stream(
128
115
params : dict [str , Any ] | None = None ,
129
116
json : dict [str , Any ] | None = None ,
130
117
form : dict [str , Any ] | None = None ,
131
- headers : dict [str , Any ] = {},
132
- ) -> tuple [Headers , BodyGeneratorFunction ]:
118
+ ) -> AsyncGenerator [bytes , None ]:
133
119
"""Request a url and and return the raw response as a stream of bytes"""
134
120
135
- headers , body = await self ._request_stream (log , url , method , params , json , form , True , headers )
136
- return (headers , body )
121
+ return self ._request_stream (log , url , method , params , json , form , True )
137
122
138
123
@abc .abstractmethod
139
- async def _request_stream (
124
+ def _request_stream (
140
125
self ,
141
126
log : Logger ,
142
127
url : str ,
@@ -146,7 +131,7 @@ async def _request_stream(
146
131
form : dict [str , Any ] | None ,
147
132
_with_token : bool ,
148
133
headers : dict [str , Any ] = {},
149
- ) -> HeadersAndBodyGenerator : ...
134
+ ) -> AsyncGenerator [ bytes , None ] : ...
150
135
151
136
# TODO(johnny): This is an unstable API.
152
137
# It may need to accept request headers, or surface response headers,
@@ -330,7 +315,7 @@ async def _request_stream(
330
315
form : dict [str , Any ] | None ,
331
316
_with_token : bool ,
332
317
headers : dict [str , Any ] = {},
333
- ) -> HeadersAndBodyGenerator :
318
+ ) -> AsyncGenerator [ bytes , None ] :
334
319
while True :
335
320
cur_delay = self .rate_limiter .delay
336
321
await asyncio .sleep (cur_delay )
@@ -345,17 +330,14 @@ async def _request_stream(
345
330
)
346
331
headers [self .token_source .authorization_header ] = header_value
347
332
348
- resp = await self .inner .request (
333
+ async with self .inner .request (
349
334
headers = headers ,
350
335
json = json ,
351
336
data = form ,
352
337
method = method ,
353
338
params = params ,
354
339
url = url ,
355
- )
356
-
357
- should_release_response = True
358
- try :
340
+ ) as resp :
359
341
self .rate_limiter .update (cur_delay , resp .status == 429 )
360
342
361
343
if resp .status == 429 :
@@ -384,17 +366,7 @@ async def _request_stream(
384
366
else :
385
367
resp .raise_for_status ()
386
368
387
- async def body_generator () -> AsyncGenerator [bytes , None ]:
388
- try :
389
- async for chunk in resp .content .iter_any ():
390
- yield chunk
391
- finally :
392
- await resp .release ()
393
-
394
- headers = Headers ({k : v for k , v in resp .headers .items ()})
395
- should_release_response = False
396
- return (headers , body_generator )
369
+ async for chunk in resp .content .iter_any ():
370
+ yield chunk
397
371
398
- finally :
399
- if should_release_response :
400
- await resp .release ()
372
+ return
0 commit comments