1
+ # Copyright 2025 Planet Labs PBC.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ # use this file except in compliance with the License. You may obtain a copy of
5
+ # the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations under
13
+ # the License.
14
+
1
15
import asyncio
2
16
from pathlib import Path
3
17
from typing import AsyncIterator , Awaitable , Optional , Tuple , Type , TypeVar , Union , cast
4
18
from planet .constants import PLANET_BASE_URL
5
19
from planet .exceptions import MissingResource
6
20
from planet .http import Session
7
- from planet .models import Mosaic , Paged , Quad , Response , Series , StreamingBody
21
+ from planet .models import GeoInterface , Mosaic , Paged , Quad , Response , Series , StreamingBody
8
22
from uuid import UUID
9
23
10
24
BASE_URL = f'{ PLANET_BASE_URL } /basemaps/v1'
@@ -49,7 +63,7 @@ class MosaicsClient:
49
63
>>>
50
64
>>> async def main():
51
65
... async with Session() as sess:
52
- ... cl = sess.client('data ')
66
+ ... cl = sess.client('mosaics ')
53
67
... # use client here
54
68
...
55
69
>>> asyncio.run(main())
@@ -74,7 +88,7 @@ def _call_sync(self, f: Awaitable[T]) -> T:
74
88
return self ._session ._call_sync (f )
75
89
76
90
def _url (self , path : str ) -> str :
77
- return f"{ BASE_URL } /{ path } "
91
+ return f"{ self . _base_url } /{ path } "
78
92
79
93
async def _get_by_name (self , path : str , pager : Type [Paged ],
80
94
name : str ) -> dict :
@@ -88,7 +102,12 @@ async def _get_by_name(self, path: str, pager: Type[Paged],
88
102
listing = response .json ()[pager .ITEMS_KEY ]
89
103
if len (listing ):
90
104
return listing [0 ]
91
- raise MissingResource (f"{ name } not found" )
105
+ # mimic the response for 404 when search is empty
106
+ resource = "Mosaic"
107
+ if path == "series" :
108
+ resource = "Series"
109
+ raise MissingResource ('{"message":"%s Not Found: %s"}' %
110
+ (resource , name ))
92
111
93
112
async def _get_by_id (self , path : str , id : str ) -> dict :
94
113
response = await self ._session .request (method = "GET" ,
@@ -130,7 +149,7 @@ async def list_series(
130
149
name_contains : Optional [str ] = None ,
131
150
interval : Optional [str ] = None ,
132
151
acquired_gt : Optional [str ] = None ,
133
- acquired_lt : Optional [str ] = None ) -> AsyncIterator [dict ]:
152
+ acquired_lt : Optional [str ] = None ) -> AsyncIterator [Series ]:
134
153
"""
135
154
List the series you have access to.
136
155
@@ -157,7 +176,7 @@ async def list_series(
157
176
params = params ,
158
177
)
159
178
async for item in _SeriesPage (resp , self ._session .request ):
160
- yield item
179
+ yield Series ( item )
161
180
162
181
async def list_mosaics (
163
182
self ,
@@ -166,8 +185,7 @@ async def list_mosaics(
166
185
interval : Optional [str ] = None ,
167
186
acquired_gt : Optional [str ] = None ,
168
187
acquired_lt : Optional [str ] = None ,
169
- latest : bool = False ,
170
- ) -> AsyncIterator [dict ]:
188
+ ) -> AsyncIterator [Mosaic ]:
171
189
"""
172
190
List the mosaics you have access to.
173
191
@@ -188,15 +206,13 @@ async def list_mosaics(
188
206
params ["acquired__gt" ] = acquired_gt
189
207
if acquired_lt :
190
208
params ["acquired__lt" ] = acquired_lt
191
- if latest :
192
- params ["latest" ] = "yes"
193
209
resp = await self ._session .request (
194
210
method = 'GET' ,
195
211
url = self ._url ("mosaics" ),
196
212
params = params ,
197
213
)
198
214
async for item in _MosaicsPage (resp , self ._session .request ):
199
- yield item
215
+ yield Mosaic ( item )
200
216
201
217
async def list_series_mosaics (
202
218
self ,
@@ -206,7 +222,7 @@ async def list_series_mosaics(
206
222
acquired_gt : Optional [str ] = None ,
207
223
acquired_lt : Optional [str ] = None ,
208
224
latest : bool = False ,
209
- ) -> AsyncIterator [dict ]:
225
+ ) -> AsyncIterator [Mosaic ]:
210
226
"""
211
227
List the mosaics in a series.
212
228
@@ -218,6 +234,7 @@ async def list_series_mosaics(
218
234
print(m)
219
235
```
220
236
"""
237
+ series_id = series
221
238
if isinstance (series , Series ):
222
239
series_id = series ["id" ]
223
240
elif not _is_uuid (series ):
@@ -238,15 +255,15 @@ async def list_series_mosaics(
238
255
params = params ,
239
256
)
240
257
async for item in _MosaicsPage (resp , self ._session .request ):
241
- yield item
258
+ yield Mosaic ( item )
242
259
243
260
async def list_quads (self ,
244
261
/ ,
245
262
mosaic : Union [Mosaic , str ],
246
263
* ,
247
264
minimal : bool = False ,
248
265
bbox : Optional [BBox ] = None ,
249
- geometry : Optional [dict ] = None ,
266
+ geometry : Optional [Union [ dict , GeoInterface ] ] = None ,
250
267
summary : bool = False ) -> AsyncIterator [Quad ]:
251
268
"""
252
269
List the a mosaic's quads.
@@ -262,6 +279,8 @@ async def list_quads(self,
262
279
"""
263
280
mosaic = await self ._resolve_mosaic (mosaic )
264
281
if geometry :
282
+ if isinstance (geometry , GeoInterface ):
283
+ geometry = geometry .__geo_interface__
265
284
resp = await self ._quads_geometry (mosaic ,
266
285
geometry ,
267
286
minimal ,
@@ -364,14 +383,6 @@ async def download_quad(self,
364
383
directory : str = "." ,
365
384
overwrite : bool = False ,
366
385
progress_bar : bool = False ):
367
- url = quad ["_links" ]["download" ]
368
- Path (directory ).mkdir (exist_ok = True , parents = True )
369
- async with self ._session .stream (method = 'GET' , url = url ) as resp :
370
- body = StreamingBody (resp )
371
- dest = Path (directory , body .name )
372
- await body .write (dest ,
373
- overwrite = overwrite ,
374
- progress_bar = progress_bar )
375
386
"""
376
387
Download a quad to a directory.
377
388
@@ -382,6 +393,14 @@ async def download_quad(self,
382
393
await client.download_quad(quad)
383
394
```
384
395
"""
396
+ url = quad ["_links" ]["download" ]
397
+ Path (directory ).mkdir (exist_ok = True , parents = True )
398
+ async with self ._session .stream (method = 'GET' , url = url ) as resp :
399
+ body = StreamingBody (resp )
400
+ dest = Path (directory , body .name )
401
+ await body .write (dest ,
402
+ overwrite = overwrite ,
403
+ progress_bar = progress_bar )
385
404
386
405
async def download_quads (self ,
387
406
/ ,
@@ -390,7 +409,8 @@ async def download_quads(self,
390
409
directory : Optional [str ] = None ,
391
410
overwrite : bool = False ,
392
411
bbox : Optional [BBox ] = None ,
393
- geometry : Optional [dict ] = None ,
412
+ geometry : Optional [Union [dict ,
413
+ GeoInterface ]] = None ,
394
414
progress_bar : bool = False ,
395
415
concurrency : int = 4 ):
396
416
"""
0 commit comments