@@ -117,6 +117,17 @@ def put(self, path: str, body: Dict = None, files: Dict = None, headers: Dict =
117117 """
118118 return self ._request ('PUT' , path , body , files , headers )
119119
120+ def post_and_get_stream (self , path : str , body : Dict = None , files : Dict = None , headers : Dict = None ):
121+ """
122+ Sends a POST request to the Lara API and yields streaming responses.
123+ :param path: The path to send the request to.
124+ :param body: The parameters to send with the request.
125+ :param files: The files to send with the request. If present, request will be sent as multipart/form-data.
126+ :param headers: Additional headers to include in the request.
127+ :return: A generator yielding streaming responses.
128+ """
129+ return self ._request_stream ('POST' , path , body , files , headers )
130+
120131 def _request (self , method : str , path : str , body : Dict = None , files : Dict = None , headers : Dict = None ) -> Optional [Union [Dict , List , bytes ]]:
121132 if not path .startswith ('/' ):
122133 path = '/' + path
@@ -148,4 +159,52 @@ def _request(self, method: str, path: str, body: Dict = None, files: Dict = None
148159 if "text/csv" in response .headers .get ('Content-Type' , '' ):
149160 return response .content
150161 return response .json ().get ('content' , None )
151- raise LaraApiError .from_response (response )
162+ raise LaraApiError .from_response (response )
163+
164+ def _request_stream (self , method : str , path : str , body : Dict = None , files : Dict = None , headers : Dict = None ):
165+ if not path .startswith ('/' ):
166+ path = '/' + path
167+
168+ _headers = {
169+ 'X-HTTP-Method-Override' : method ,
170+ 'Date' : datetime .datetime .now (datetime .timezone .utc ).isoformat (),
171+ 'X-Lara-SDK-Name' : self .sdk_name ,
172+ 'X-Lara-SDK-Version' : self .sdk_version
173+ }
174+
175+ if headers is not None :
176+ _headers .update (headers )
177+
178+ if body is not None :
179+ body = {k : v for k , v in body .items () if v is not None }
180+
181+ if len (body ) > 0 :
182+ encoded_body = json .dumps (body , ensure_ascii = False , separators = (',' , ':' )).encode ('UTF-8' )
183+ _headers ['Content-MD5' ] = hashlib .md5 (encoded_body ).hexdigest ()
184+
185+ if files is not None :
186+ response = self .session .request ('POST' , f'{ self .base_url } { path } ' , headers = _headers , data = body , files = files , stream = True )
187+ else :
188+ response = self .session .request ('POST' , f'{ self .base_url } { path } ' , headers = _headers , json = body , stream = True )
189+
190+ buffer = ''
191+ for chunk in response .iter_content (chunk_size = None , decode_unicode = True ):
192+ if chunk :
193+ buffer += chunk
194+ lines = buffer .split ('\n ' )
195+ buffer = lines .pop ()
196+
197+ for line in lines :
198+ if line .strip ():
199+ try :
200+ parsed = json .loads (line )
201+ yield parsed .get ('data' , parsed ).get ('content' )
202+ except (json .JSONDecodeError , AttributeError ):
203+ pass
204+
205+ if buffer .strip ():
206+ try :
207+ parsed = json .loads (buffer )
208+ yield parsed .get ('data' , parsed ).get ('content' )
209+ except (json .JSONDecodeError , AttributeError ):
210+ pass
0 commit comments