@@ -331,6 +331,8 @@ def stac_validate(
331331 errors : Errors ,
332332 context : Context ,
333333 method : Method = Method .GET ,
334+ open_assets_urls : bool = True ,
335+ headers : Optional [dict ] = None ,
334336) -> None :
335337 if not body :
336338 errors += f"[{ context } ] : { method } { url } body was empty when running stac-validate and stac-check"
@@ -350,8 +352,14 @@ def stac_validate(
350352 errors += f"[{ context } ] : { method } { url } '{ body .get ('id' )} ' failed pystac hydration: { e } "
351353
352354 if _type in ["Collection" , "Feature" ]:
355+ logger .debug (f"stac-validator validation: { url } " )
353356 if not (
354- stac_validator := StacValidate (links = True , assets = True )
357+ stac_validator := StacValidate (
358+ links = True ,
359+ assets = True ,
360+ assets_open_urls = open_assets_urls ,
361+ headers = headers or {},
362+ )
355363 ).validate_dict (body ):
356364 errors += f"[{ context } ] : { method } { url } failed stac-validator validation: { stac_validator .message } "
357365
@@ -365,9 +373,12 @@ def stac_check(
365373 warnings : Warnings ,
366374 context : Context ,
367375 method : Method = Method .GET ,
376+ open_assets_urls : bool = True ,
377+ headers : Optional [dict ] = None ,
368378) -> None :
369379 try :
370- linter = Linter (url )
380+ logger .debug (f"stac-check validation: { url } " )
381+ linter = Linter (url , assets_open_urls = open_assets_urls , headers = headers or {})
371382 if not linter .valid_stac :
372383 errors += f"[{ context } ] : { method } { url } is not a valid STAC object: { linter .error_msg } "
373384 if msgs := linter .best_practices_msg [1 :]: # first msg is a header, so skip
@@ -548,6 +559,7 @@ def validate_api(
548559 query_config : QueryConfig ,
549560 transaction_collection : Optional [str ],
550561 headers : Optional [Dict [str , str ]],
562+ open_assets_urls : bool = True ,
551563) -> Tuple [Warnings , Errors ]:
552564 warnings = Warnings ()
553565 errors = Errors ()
@@ -598,13 +610,17 @@ def validate_api(
598610
599611 if "collections" in ccs_to_validate :
600612 logger .info ("Validating STAC API - Collections conformance class." )
601- validate_collections (landing_page_body , collection , errors , warnings , r_session )
613+ validate_collections (
614+ landing_page_body , collection , errors , warnings , r_session , open_assets_urls
615+ )
602616
603617 conforms_to = landing_page_body .get ("conformsTo" , [])
604618
605619 if "features" in ccs_to_validate :
606620 logger .info ("Validating STAC API - Features conformance class." )
607- validate_collections (landing_page_body , collection , errors , warnings , r_session )
621+ validate_collections (
622+ landing_page_body , collection , errors , warnings , r_session , open_assets_urls
623+ )
608624 validate_features (
609625 landing_page_body ,
610626 conforms_to ,
@@ -613,7 +629,8 @@ def validate_api(
613629 warnings ,
614630 errors ,
615631 r_session ,
616- validate_pagination = validate_pagination ,
632+ validate_pagination ,
633+ open_assets_urls ,
617634 )
618635
619636 if "transaction" in ccs_to_validate :
@@ -664,6 +681,7 @@ def validate_api(
664681 conformance_classes = ccs_to_validate ,
665682 r_session = r_session ,
666683 validate_pagination = validate_pagination ,
684+ open_assets_urls = open_assets_urls ,
667685 )
668686
669687 if "item-search#fields" in ccs_to_validate :
@@ -963,6 +981,7 @@ def validate_collections(
963981 errors : Errors ,
964982 warnings : Warnings ,
965983 r_session : Session ,
984+ open_assets_urls : bool = True ,
966985) -> None :
967986 if not (data_link := link_by_rel (root_body ["links" ], "data" )):
968987 errors += f"[{ Context .COLLECTIONS } ] /: Link[rel=data] must href /collections"
@@ -1019,7 +1038,15 @@ def validate_collections(
10191038 )
10201039 else :
10211040 for body in collections_list :
1022- stac_validate (collections_url , body , errors , Context .COLLECTIONS )
1041+ stac_validate (
1042+ collections_url ,
1043+ body ,
1044+ errors ,
1045+ Context .COLLECTIONS ,
1046+ Method .GET ,
1047+ open_assets_urls ,
1048+ r_session .headers ,
1049+ )
10231050
10241051 collection_url = f"{ data_link ['href' ]} /{ collection } "
10251052 _ , body , resp_headers = retrieve (
@@ -1047,8 +1074,24 @@ def validate_collections(
10471074 if not link_by_rel (body .get ("links" , []), "parent" ):
10481075 errors += f"[{ Context .COLLECTIONS } ] : { collection_url } does not have parent link"
10491076
1050- stac_validate (collection_url , body , errors , Context .COLLECTIONS )
1051- stac_check (collection_url , errors , warnings , Context .COLLECTIONS )
1077+ stac_validate (
1078+ collection_url ,
1079+ body ,
1080+ errors ,
1081+ Context .COLLECTIONS ,
1082+ Method .GET ,
1083+ open_assets_urls ,
1084+ r_session .headers ,
1085+ )
1086+ stac_check (
1087+ collection_url ,
1088+ errors ,
1089+ warnings ,
1090+ Context .COLLECTIONS ,
1091+ Method .GET ,
1092+ open_assets_urls ,
1093+ r_session .headers ,
1094+ )
10521095
10531096 # todo: collection pagination
10541097
@@ -1062,6 +1105,7 @@ def validate_features(
10621105 errors : Errors ,
10631106 r_session : Session ,
10641107 validate_pagination : bool ,
1108+ open_assets_urls : bool = True ,
10651109) -> None :
10661110 if not geometry :
10671111 errors += f"[{ Context .FEATURES } ] Geometry parameter required for running Features validations."
@@ -1132,7 +1176,15 @@ def validate_features(
11321176 if not body :
11331177 errors += f"[{ Context .FEATURES } ] GET { collection_items_url } returned an empty body"
11341178 else :
1135- stac_validate (collection_items_url , body , errors , Context .FEATURES )
1179+ stac_validate (
1180+ collection_items_url ,
1181+ body ,
1182+ errors ,
1183+ Context .FEATURES ,
1184+ Method .GET ,
1185+ open_assets_urls ,
1186+ r_session .headers ,
1187+ )
11361188
11371189 item_url = link_by_rel (body .get ("features" , [])[0 ]["links" ], "self" )[
11381190 "href"
@@ -1147,8 +1199,24 @@ def validate_features(
11471199 r_session = r_session ,
11481200 )
11491201
1150- stac_validate (item_url , body , errors , Context .FEATURES )
1151- stac_check (item_url , errors , warnings , Context .FEATURES )
1202+ stac_validate (
1203+ item_url ,
1204+ body ,
1205+ errors ,
1206+ Context .FEATURES ,
1207+ Method .GET ,
1208+ open_assets_urls ,
1209+ r_session .headers ,
1210+ )
1211+ stac_check (
1212+ item_url ,
1213+ errors ,
1214+ warnings ,
1215+ Context .FEATURES ,
1216+ Method .GET ,
1217+ open_assets_urls ,
1218+ r_session .headers ,
1219+ )
11521220
11531221 # Validate Features non-existent item
11541222 if not (collections_link := link_by_rel (root_links , "data" )):
@@ -1195,7 +1263,15 @@ def validate_features(
11951263 if not link_by_rel (body .get ("links" , []), "root" ):
11961264 errors += f"[{ Context .FEATURES } ] GET { collection_items_url } does not have root link"
11971265
1198- stac_validate (collection_items_url , body , errors , Context .FEATURES )
1266+ stac_validate (
1267+ collection_items_url ,
1268+ body ,
1269+ errors ,
1270+ Context .FEATURES ,
1271+ Method .GET ,
1272+ open_assets_urls ,
1273+ r_session .headers ,
1274+ )
11991275
12001276 item = next (iter (body .get ("features" , [])), None )
12011277
@@ -1233,8 +1309,24 @@ def validate_features(
12331309 if not link_by_rel (body .get ("links" , []), "parent" ):
12341310 errors += f"[{ Context .FEATURES } ] GET { item_url } does not have parent link"
12351311
1236- stac_validate (item_url , body , errors , Context .FEATURES )
1237- stac_check (item_url , errors , warnings , Context .FEATURES )
1312+ stac_validate (
1313+ item_url ,
1314+ body ,
1315+ errors ,
1316+ Context .FEATURES ,
1317+ Method .GET ,
1318+ open_assets_urls ,
1319+ r_session .headers ,
1320+ )
1321+ stac_check (
1322+ item_url ,
1323+ errors ,
1324+ warnings ,
1325+ Context .FEATURES ,
1326+ Method .GET ,
1327+ open_assets_urls ,
1328+ r_session .headers ,
1329+ )
12381330
12391331 if validate_pagination :
12401332 # Items pagination validation
@@ -1270,6 +1362,7 @@ def validate_item_search(
12701362 conformance_classes : List [str ],
12711363 r_session : Session ,
12721364 validate_pagination : bool ,
1365+ open_assets_urls : bool = True ,
12731366) -> None :
12741367 links = root_body .get ("links" )
12751368
@@ -1317,7 +1410,14 @@ def validate_item_search(
13171410 )
13181411
13191412 if body :
1320- stac_validate (search_url , body , errors , Context .ITEM_SEARCH )
1413+ stac_validate (
1414+ search_url ,
1415+ body ,
1416+ errors ,
1417+ Context .ITEM_SEARCH ,
1418+ open_assets_urls ,
1419+ r_session .headers ,
1420+ )
13211421
13221422 validate_item_search_limit (search_url , methods , errors , r_session )
13231423 validate_item_search_bbox_xor_intersects (search_url , methods , errors , r_session )
0 commit comments