@@ -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 : dict = {},
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 ,
362+ )
355363 ).validate_dict (body ):
356364 errors += f"[{ context } ] : { method } { url } failed stac-validator validation: { stac_validator .message } "
357365
@@ -365,9 +373,11 @@ def stac_check(
365373 warnings : Warnings ,
366374 context : Context ,
367375 method : Method = Method .GET ,
376+ open_assets_urls : bool = True ,
377+ headers : dict = {},
368378) -> None :
369379 try :
370- linter = Linter (url )
380+ linter = Linter (url , assets_open_urls = open_assets_urls , headers = headers )
371381 if not linter .valid_stac :
372382 errors += f"[{ context } ] : { method } { url } is not a valid STAC object: { linter .error_msg } "
373383 if msgs := linter .best_practices_msg [1 :]: # first msg is a header, so skip
@@ -548,6 +558,7 @@ def validate_api(
548558 query_config : QueryConfig ,
549559 transaction_collection : Optional [str ],
550560 headers : Optional [Dict [str , str ]],
561+ open_assets_urls : bool = True ,
551562) -> Tuple [Warnings , Errors ]:
552563 warnings = Warnings ()
553564 errors = Errors ()
@@ -598,13 +609,17 @@ def validate_api(
598609
599610 if "collections" in ccs_to_validate :
600611 logger .info ("Validating STAC API - Collections conformance class." )
601- validate_collections (landing_page_body , collection , errors , warnings , r_session )
612+ validate_collections (
613+ landing_page_body , collection , errors , warnings , r_session , open_assets_urls
614+ )
602615
603616 conforms_to = landing_page_body .get ("conformsTo" , [])
604617
605618 if "features" in ccs_to_validate :
606619 logger .info ("Validating STAC API - Features conformance class." )
607- validate_collections (landing_page_body , collection , errors , warnings , r_session )
620+ validate_collections (
621+ landing_page_body , collection , errors , warnings , r_session , open_assets_urls
622+ )
608623 validate_features (
609624 landing_page_body ,
610625 conforms_to ,
@@ -613,7 +628,8 @@ def validate_api(
613628 warnings ,
614629 errors ,
615630 r_session ,
616- validate_pagination = validate_pagination ,
631+ validate_pagination ,
632+ open_assets_urls ,
617633 )
618634
619635 if "transaction" in ccs_to_validate :
@@ -664,6 +680,7 @@ def validate_api(
664680 conformance_classes = ccs_to_validate ,
665681 r_session = r_session ,
666682 validate_pagination = validate_pagination ,
683+ open_assets_urls = open_assets_urls ,
667684 )
668685
669686 if "item-search#fields" in ccs_to_validate :
@@ -963,6 +980,7 @@ def validate_collections(
963980 errors : Errors ,
964981 warnings : Warnings ,
965982 r_session : Session ,
983+ open_assets_urls : bool = True ,
966984) -> None :
967985 if not (data_link := link_by_rel (root_body ["links" ], "data" )):
968986 errors += f"[{ Context .COLLECTIONS } ] /: Link[rel=data] must href /collections"
@@ -1019,7 +1037,15 @@ def validate_collections(
10191037 )
10201038 else :
10211039 for body in collections_list :
1022- stac_validate (collections_url , body , errors , Context .COLLECTIONS )
1040+ stac_validate (
1041+ collections_url ,
1042+ body ,
1043+ errors ,
1044+ Context .COLLECTIONS ,
1045+ Method .GET ,
1046+ open_assets_urls ,
1047+ r_session .headers ,
1048+ )
10231049
10241050 collection_url = f"{ data_link ['href' ]} /{ collection } "
10251051 _ , body , resp_headers = retrieve (
@@ -1047,8 +1073,24 @@ def validate_collections(
10471073 if not link_by_rel (body .get ("links" , []), "parent" ):
10481074 errors += f"[{ Context .COLLECTIONS } ] : { collection_url } does not have parent link"
10491075
1050- stac_validate (collection_url , body , errors , Context .COLLECTIONS )
1051- stac_check (collection_url , errors , warnings , Context .COLLECTIONS )
1076+ stac_validate (
1077+ collection_url ,
1078+ body ,
1079+ errors ,
1080+ Context .COLLECTIONS ,
1081+ Method .GET ,
1082+ open_assets_urls ,
1083+ r_session .headers ,
1084+ )
1085+ stac_check (
1086+ collection_url ,
1087+ errors ,
1088+ warnings ,
1089+ Context .COLLECTIONS ,
1090+ Method .GET ,
1091+ open_assets_urls ,
1092+ r_session .headers ,
1093+ )
10521094
10531095 # todo: collection pagination
10541096
@@ -1062,6 +1104,7 @@ def validate_features(
10621104 errors : Errors ,
10631105 r_session : Session ,
10641106 validate_pagination : bool ,
1107+ open_assets_urls : bool = True ,
10651108) -> None :
10661109 if not geometry :
10671110 errors += f"[{ Context .FEATURES } ] Geometry parameter required for running Features validations."
@@ -1132,7 +1175,15 @@ def validate_features(
11321175 if not body :
11331176 errors += f"[{ Context .FEATURES } ] GET { collection_items_url } returned an empty body"
11341177 else :
1135- stac_validate (collection_items_url , body , errors , Context .FEATURES )
1178+ stac_validate (
1179+ collection_items_url ,
1180+ body ,
1181+ errors ,
1182+ Context .FEATURES ,
1183+ Method .GET ,
1184+ open_assets_urls ,
1185+ r_session .headers ,
1186+ )
11361187
11371188 item_url = link_by_rel (body .get ("features" , [])[0 ]["links" ], "self" )[
11381189 "href"
@@ -1147,7 +1198,15 @@ def validate_features(
11471198 r_session = r_session ,
11481199 )
11491200
1150- stac_validate (item_url , body , errors , Context .FEATURES )
1201+ stac_validate (
1202+ item_url ,
1203+ body ,
1204+ errors ,
1205+ Context .FEATURES ,
1206+ Method .GET ,
1207+ open_assets_urls ,
1208+ r_session .headers ,
1209+ )
11511210 stac_check (item_url , errors , warnings , Context .FEATURES )
11521211
11531212 # Validate Features non-existent item
@@ -1195,7 +1254,15 @@ def validate_features(
11951254 if not link_by_rel (body .get ("links" , []), "root" ):
11961255 errors += f"[{ Context .FEATURES } ] GET { collection_items_url } does not have root link"
11971256
1198- stac_validate (collection_items_url , body , errors , Context .FEATURES )
1257+ stac_validate (
1258+ collection_items_url ,
1259+ body ,
1260+ errors ,
1261+ Context .FEATURES ,
1262+ Method .GET ,
1263+ open_assets_urls ,
1264+ r_session .headers ,
1265+ )
11991266
12001267 item = next (iter (body .get ("features" , [])), None )
12011268
@@ -1233,7 +1300,15 @@ def validate_features(
12331300 if not link_by_rel (body .get ("links" , []), "parent" ):
12341301 errors += f"[{ Context .FEATURES } ] GET { item_url } does not have parent link"
12351302
1236- stac_validate (item_url , body , errors , Context .FEATURES )
1303+ stac_validate (
1304+ item_url ,
1305+ body ,
1306+ errors ,
1307+ Context .FEATURES ,
1308+ Method .GET ,
1309+ open_assets_urls ,
1310+ r_session .headers ,
1311+ )
12371312 stac_check (item_url , errors , warnings , Context .FEATURES )
12381313
12391314 if validate_pagination :
@@ -1270,6 +1345,7 @@ def validate_item_search(
12701345 conformance_classes : List [str ],
12711346 r_session : Session ,
12721347 validate_pagination : bool ,
1348+ open_assets_urls : bool = True ,
12731349) -> None :
12741350 links = root_body .get ("links" )
12751351
@@ -1317,7 +1393,14 @@ def validate_item_search(
13171393 )
13181394
13191395 if body :
1320- stac_validate (search_url , body , errors , Context .ITEM_SEARCH )
1396+ stac_validate (
1397+ search_url ,
1398+ body ,
1399+ errors ,
1400+ Context .ITEM_SEARCH ,
1401+ open_assets_urls ,
1402+ r_session .headers ,
1403+ )
13211404
13221405 validate_item_search_limit (search_url , methods , errors , r_session )
13231406 validate_item_search_bbox_xor_intersects (search_url , methods , errors , r_session )
0 commit comments