5757
5858# Load all the planet api keys from the environment and setup a cycle so we can always use the next one.
5959try :
60- PLANET_API_KEYS = itertools .cycle (os .environ .get ("PLANET_API_KEYS" ).split (":" ))
60+ PLANET_API_KEYS = itertools .cycle (
61+ os .environ .get (
62+ "PLANET_API_KEYS" ,
63+ ).split (":" )
64+ )
6165except NameError :
6266 PLANET_API_KEYS = None
6367
@@ -95,26 +99,27 @@ def get_auth(credentials) -> httpx.BasicAuth:
9599 """Create a httpx auth for the planet apis."""
96100 # Use the api key if available, otherwise pass through basic credentials from the user.
97101
98- if PLANET_API_KEYS is not None :
99- api_key = next (PLANET_API_KEYS )
100- auth = httpx .BasicAuth (username = api_key , password = "" )
101- elif credentials is not None :
102+ if credentials is not None :
103+ api_key = credentials .username
102104 auth = httpx .BasicAuth (
103105 username = credentials .username , password = credentials .password
104106 )
107+
108+ elif PLANET_API_KEYS is not None :
109+ api_key = next (PLANET_API_KEYS )
110+ auth = httpx .BasicAuth (username = api_key , password = "" )
111+
105112 else :
106113 raise fastapi .HTTPException (
107114 status_code = 401 , detail = "Credentials were not provided."
108115 )
109116
110- return auth
117+ return auth , api_key
111118
112119
113- def get_authenticated_client (credentials ) -> httpx .Client :
120+ def get_authenticated_client (auth ) -> httpx .Client :
114121 """Create a httpx client with correct auth for the planet apis."""
115122
116- auth = get_auth (credentials )
117-
118123 return httpx .AsyncClient (
119124 auth = auth ,
120125 verify = False ,
@@ -237,14 +242,15 @@ async def get_search(
237242 includes .add (field [1 :] if field [0 ] in "+ " else field )
238243 search_request ["fields" ] = {"include" : includes , "exclude" : excludes }
239244
240- return await prepare_search (
245+ return await post_search (
241246 search_request = POST_REQUEST_MODEL (** search_request ),
242247 request = request ,
243248 credentials = credentials ,
244249 )
245250
246251
247- async def prepare_search (
252+ @app .post ("/search" )
253+ async def post_search (
248254 search_request : POST_REQUEST_MODEL ,
249255 request : Request ,
250256 credentials : Annotated [
@@ -259,162 +265,85 @@ async def prepare_search(
259265 Returns:
260266 ItemCollection: The items.
261267 """
262-
263- client = get_authenticated_client (credentials )
264268 base_url = get_base_url (request )
265269
266- auth = get_auth (credentials )
267-
268- search_request .limit = (
269- MAX_ITEMS if search_request .limit > MAX_ITEMS else search_request .limit
270- )
270+ if token := search_request .token :
271+ token_parts = FERNET .decrypt (token ).decode ("utf-8" ).split ("\\ " )
271272
272- if search_request .ids :
273-
274- all_collections = (
275- search_request .collections
276- if search_request .collections
277- else await get_collections (client )
273+ credentials = fastapi .security .HTTPBasicCredentials (
274+ username = token_parts [1 ], password = ""
278275 )
279276
280- all_items = []
281-
282- for item_id in search_request .ids :
283- for collection_id in all_collections :
284- try :
285- item = await get_item (
286- collection_id = collection_id ,
287- item_id = item_id ,
288- request = request ,
289- credentials = credentials ,
290- )
291- all_items .append (item )
292- except httpx .HTTPStatusError : # unable to find item in catalogue
293- pass
294-
295- return ItemCollection (
296- ** {
297- "type" : "FeatureCollection" ,
298- "features" : all_items ,
299- "links" : [
300- {
301- "rel" : "self" ,
302- "href" : f"{ base_url } search" ,
303- "type" : "application/geo+json" ,
304- },
305- {"rel" : "root" , "href" : base_url , "type" : "application/json" },
306- ],
307- }
308- )
309-
310- else :
311- if token := search_request .token :
312- token_url = FERNET .decrypt (token ).decode ("utf-8" )
313- planet_response = await client .get (token_url )
277+ auth , api_key = get_auth (credentials )
278+ client = get_authenticated_client (auth = auth )
314279
315- else :
316- planet_parameters , planet_request = stac_to_planet_request (
317- stac_request = search_request
318- )
280+ planet_response = await client .get (token_parts [0 ])
319281
320- planet_response = await client .post (
321- "https://api.planet.com/data/v1/quick-search" ,
322- params = planet_parameters ,
323- json = planet_request ,
324- )
282+ else :
325283
326- planet_response .raise_for_status ()
284+ auth , api_key = get_auth (credentials )
285+ client = get_authenticated_client (auth )
327286
328- return planet_to_stac_response (
329- planet_response = planet_response . json (), base_url = base_url , auth = auth
287+ search_request . limit = (
288+ MAX_ITEMS if search_request . limit > MAX_ITEMS else search_request . limit
330289 )
331290
291+ if search_request .ids :
332292
333- @app .post ("/search" )
334- async def post_search (
335- search_request : POST_REQUEST_MODEL ,
336- request : Request ,
337- credentials : Annotated [
338- fastapi .security .HTTPBasicCredentials , fastapi .Depends (security )
339- ],
340- ) -> ItemCollection :
341- """Search planet items.
342-
343- Args:
344- search request (BaseSearchPostRequest): The search request.
345-
346- Returns:
347- ItemCollection: The items.
348- """
349-
350- client = get_authenticated_client (credentials )
351- base_url = get_base_url (request )
352-
353- auth = get_auth (credentials )
354-
355- search_request .limit = (
356- MAX_ITEMS if search_request .limit > MAX_ITEMS else search_request .limit
357- )
293+ all_collections = (
294+ search_request .collections
295+ if search_request .collections
296+ else await get_collections (client )
297+ )
358298
359- if search_request .ids :
299+ all_items = []
300+
301+ for item_id in search_request .ids :
302+ for collection_id in all_collections :
303+ try :
304+ item = await get_item (
305+ collection_id = collection_id ,
306+ item_id = item_id ,
307+ request = request ,
308+ credentials = credentials ,
309+ )
310+ all_items .append (item )
311+ except httpx .HTTPStatusError : # unable to find item in catalogue
312+ pass
313+
314+ return ItemCollection (
315+ ** {
316+ "type" : "FeatureCollection" ,
317+ "features" : all_items ,
318+ "links" : [
319+ {
320+ "rel" : "self" ,
321+ "href" : f"{ base_url } search" ,
322+ "type" : "application/geo+json" ,
323+ },
324+ {"rel" : "root" , "href" : base_url , "type" : "application/json" },
325+ ],
326+ }
327+ )
360328
361- all_collections = (
362- search_request .collections
363- if search_request .collections
364- else await get_collections (client )
329+ planet_parameters , planet_request = stac_to_planet_request (
330+ stac_request = search_request
365331 )
366332
367- all_items = []
368-
369- for item_id in search_request .ids :
370- for collection_id in all_collections :
371- try :
372- item = await get_item (
373- collection_id = collection_id ,
374- item_id = item_id ,
375- request = request ,
376- credentials = credentials ,
377- )
378- all_items .append (item )
379- except httpx .HTTPStatusError : # unable to find item in catalogue
380- pass
381-
382- return ItemCollection (
383- ** {
384- "type" : "FeatureCollection" ,
385- "features" : all_items ,
386- "links" : [
387- {
388- "rel" : "self" ,
389- "href" : f"{ base_url } search" ,
390- "type" : "application/geo+json" ,
391- },
392- {"rel" : "root" , "href" : base_url , "type" : "application/json" },
393- ],
394- }
333+ planet_response = await client .post (
334+ "https://api.planet.com/data/v1/quick-search" ,
335+ params = planet_parameters ,
336+ json = planet_request ,
395337 )
396338
397- else :
398- if token := search_request .token :
399- token_url = FERNET .decrypt (token ).decode ("utf-8" )
400- planet_response = await client .get (token_url )
401-
402- else :
403- planet_parameters , planet_request = stac_to_planet_request (
404- stac_request = search_request
405- )
406-
407- planet_response = await client .post (
408- "https://api.planet.com/data/v1/quick-search" ,
409- params = planet_parameters ,
410- json = planet_request ,
411- )
412-
413- planet_response .raise_for_status ()
339+ planet_response .raise_for_status ()
414340
415- return planet_to_stac_response (
416- planet_response = planet_response .json (), base_url = base_url , auth = auth
417- )
341+ return planet_to_stac_response (
342+ planet_response = planet_response .json (),
343+ base_url = base_url ,
344+ auth = auth ,
345+ api_key = api_key ,
346+ )
418347
419348
420349@app .get ("/collections/{collection_id}/items" )
@@ -432,30 +361,18 @@ async def get_item_collection(
432361 Returns:
433362 ItemCollection: The items.
434363 """
435- client = get_authenticated_client (credentials )
436- base_url = get_base_url (request )
437-
438- auth = get_auth (credentials )
439-
440364 query_params = dict (request ._query_params )
441365
442- limit = int (query_params .get ("limit" , MAX_ITEMS ))
443- query_params ["limit" ] = MAX_ITEMS if limit > MAX_ITEMS else limit
444-
445- planet_parameters , planet_request = stac_to_planet_request (
446- stac_request = BaseSearchPostRequest (collections = [collection_id ], ** query_params )
447- )
448-
449- planet_response = await client .post (
450- "https://api.planet.com/data/v1/quick-search" ,
451- params = planet_parameters ,
452- json = planet_request ,
453- )
454-
455- planet_response .raise_for_status ()
366+ search_request = {
367+ "collections" : [collection_id ],
368+ "limit" : int (query_params .get ("limit" , MAX_ITEMS )),
369+ "token" : query_params .get ("token" , None ),
370+ }
456371
457- return planet_to_stac_response (
458- planet_response = planet_response .json (), base_url = base_url , auth = auth
372+ return await post_search (
373+ search_request = POST_REQUEST_MODEL (** search_request ),
374+ request = request ,
375+ credentials = credentials ,
459376 )
460377
461378
@@ -476,11 +393,10 @@ async def get_item(
476393 Returns:
477394 Item: The item.
478395 """
479- client = get_authenticated_client (credentials )
396+ auth , _ = get_auth (credentials )
397+ client = get_authenticated_client (auth )
480398 base_url = get_base_url (request )
481399
482- auth = get_auth (credentials )
483-
484400 planet_response = await client .get (
485401 f"https://api.planet.com/data/v1/item-types/{ collection_id } /items/{ item_id } " ,
486402 )
@@ -511,11 +427,10 @@ async def get_item_thumbnail(
511427 Returns:
512428 Response: Thumbnail image
513429 """
514- client = get_authenticated_client (credentials )
430+ auth , _ = get_auth (credentials )
431+ client = get_authenticated_client (auth )
515432 base_url = get_base_url (request )
516433
517- auth = get_auth (credentials )
518-
519434 planet_response = await client .get (
520435 f"https://api.planet.com/data/v1/item-types/{ collection_id } /items/{ item_id } " ,
521436 )
0 commit comments