11"""Planet Subscriptions API Python client."""
22
33import logging
4- from typing import AsyncIterator , Optional , Set
4+ from typing import AsyncIterator , Literal , Optional , Sequence
55
66from planet .exceptions import APIError , ClientError
77from planet .http import Session
@@ -58,7 +58,7 @@ def __init__(self,
5858 self ._base_url = self ._base_url [:- 1 ]
5959
6060 async def list_subscriptions (self ,
61- status : Optional [Set [str ]] = None ,
61+ status : Optional [Sequence [str ]] = None ,
6262 limit : int = 100 ) -> AsyncIterator [dict ]:
6363 """Iterate over list of account subscriptions with optional filtering.
6464
@@ -216,16 +216,21 @@ async def get_subscription(self, subscription_id: str) -> dict:
216216
217217 async def get_results (self ,
218218 subscription_id : str ,
219- status : Optional [Set [str ]] = None ,
219+ status : Optional [Sequence [Literal [
220+ "created" ,
221+ "queued" ,
222+ "processing" ,
223+ "failed" ,
224+ "success" ]]] = None ,
220225 limit : int = 100 ) -> AsyncIterator [dict ]:
221226 """Iterate over results of a Subscription.
222227
223- Note :
228+ Notes :
224229 The name of this method is based on the API's method name. This
225230 method provides iteration over results, it does not get a
226231 single result description or return a list of descriptions.
227232
228- Args :
233+ Parameters :
229234 subscription_id (str): id of a subscription.
230235 status (Set[str]): pass result with status in this set,
231236 filter out results with status not in this set.
@@ -252,7 +257,6 @@ class _ResultsPager(Paged):
252257 resp = await self ._session .request (method = 'GET' ,
253258 url = url ,
254259 params = params )
255-
256260 async for sub in _ResultsPager (resp ,
257261 self ._session .request ,
258262 limit = limit ):
@@ -263,3 +267,41 @@ class _ResultsPager(Paged):
263267 raise
264268 except ClientError : # pragma: no cover
265269 raise
270+
271+ async def get_results_csv (
272+ self ,
273+ subscription_id : str ,
274+ status : Optional [Sequence [Literal ["created" ,
275+ "queued" ,
276+ "processing" ,
277+ "failed" ,
278+ "success" ]]] = None ,
279+ limit : int = 100 ,
280+ ) -> AsyncIterator [str ]:
281+ """Iterate over rows of results CSV for a Subscription.
282+
283+ Parameters:
284+ subscription_id (str): id of a subscription.
285+ status (Set[str]): pass result with status in this set,
286+ filter out results with status not in this set.
287+ TODO: created, updated, completed, user_id
288+
289+ Yields:
290+ str: a row from a CSV file.
291+
292+ Raises:
293+ APIError: on an API server error.
294+ ClientError: on a client error.
295+ """
296+ url = f'{ self ._base_url } /{ subscription_id } /results'
297+ params = {'status' : [val for val in status or {}], 'format' : 'csv' }
298+
299+ # Note: retries are not implemented yet. This project has
300+ # retry logic for HTTP requests, but does not handle errors
301+ # during streaming. We may want to consider a retry decorator
302+ # for this entire method a la stamina:
303+ # https://github.com/hynek/stamina.
304+ async with self ._session ._client .stream ('GET' , url ,
305+ params = params ) as response :
306+ async for line in response .aiter_lines ():
307+ yield line
0 commit comments