1
1
import json
2
2
import os
3
3
from json .decoder import JSONDecodeError
4
- from typing import List , Optional
4
+ from typing import Optional
5
5
from urllib .error import HTTPError , URLError
6
6
7
7
import click # type: ignore
22
22
class StacValidate :
23
23
def __init__ (
24
24
self ,
25
- stac_file : str = None ,
25
+ stac_file : Optional [str ] = None ,
26
+ item_collection : bool = False ,
27
+ pages : Optional [int ] = None ,
26
28
recursive : bool = False ,
27
29
max_depth : Optional [int ] = None ,
28
30
core : bool = False ,
@@ -35,6 +37,8 @@ def __init__(
35
37
log : str = "" ,
36
38
):
37
39
self .stac_file = stac_file
40
+ self .item_collection = item_collection
41
+ self .pages = pages
38
42
self .message : list = []
39
43
self .custom = custom
40
44
self .links = links
@@ -64,10 +68,10 @@ def create_err_msg(self, err_type: str, err_msg: str) -> dict:
64
68
}
65
69
66
70
def create_links_message (self ):
67
- format_valid : List [ str ] = []
68
- format_invalid : List [ str ] = []
69
- request_valid : List [ str ] = []
70
- request_invalid : List [ str ] = []
71
+ format_valid = []
72
+ format_invalid = []
73
+ request_valid = []
74
+ request_invalid = []
71
75
return {
72
76
"format_valid" : format_valid ,
73
77
"format_invalid" : format_invalid ,
@@ -267,75 +271,106 @@ def recursive_validator(self, stac_type: str) -> bool:
267
271
click .echo (json .dumps (message , indent = 4 ))
268
272
return True
269
273
270
- def validate_dict (cls , stac_content ):
271
- cls .stac_content = stac_content
272
- return cls .run ()
274
+ def validate_dict (self , stac_content ):
275
+ self .stac_content = stac_content
276
+ return self .run ()
273
277
274
- def run (cls ):
278
+ def validate_item_collection_dict (self , item_collection ):
279
+ for item in item_collection ["features" ]:
280
+ self .custom = ""
281
+ self .validate_dict (item )
282
+
283
+ def validate_item_collection (self ):
284
+ page = 1
285
+ print (f"processing page { page } " )
286
+ item_collection = fetch_and_parse_file (self .stac_file )
287
+ self .validate_item_collection_dict (item_collection )
288
+ try :
289
+ if self .pages is not None :
290
+ for _ in range (self .pages - 1 ):
291
+ if "links" in item_collection :
292
+ for link in item_collection ["links" ]:
293
+ if link ["rel" ] == "next" :
294
+ page = page + 1
295
+ print (f"processing page { page } " )
296
+ next_link = link ["href" ]
297
+ self .stac_file = next_link
298
+ item_collection = fetch_and_parse_file (self .stac_file )
299
+ self .validate_item_collection_dict (item_collection )
300
+ break
301
+ except Exception as e :
302
+ message = {}
303
+ message ["pagination_error" ] = (
304
+ f"Validating the item collection failed on page { page } : " ,
305
+ str (e ),
306
+ )
307
+ self .message .append (message )
308
+
309
+ def run (self ):
275
310
message = {}
276
311
try :
277
- if cls .stac_file is not None :
278
- cls .stac_content = fetch_and_parse_file (cls .stac_file )
279
- stac_type = get_stac_type (cls .stac_content ).upper ()
280
- cls .version = cls .stac_content ["stac_version" ]
312
+ if self .stac_file is not None and self . item_collection is False :
313
+ self .stac_content = fetch_and_parse_file (self .stac_file )
314
+ stac_type = get_stac_type (self .stac_content ).upper ()
315
+ self .version = self .stac_content ["stac_version" ]
281
316
282
- if cls .core is True :
283
- message = cls .create_message (stac_type , "core" )
284
- cls .core_validator (stac_type )
285
- message ["schema" ] = [cls .custom ]
286
- cls .valid = True
287
- elif cls .custom != "" :
288
- message = cls .create_message (stac_type , "custom" )
289
- message ["schema" ] = [cls .custom ]
290
- cls .custom_validator ()
291
- cls .valid = True
292
- elif cls .recursive :
293
- cls .valid = cls .recursive_validator (stac_type )
294
- elif cls .extensions is True :
295
- message = cls .extensions_validator (stac_type )
317
+ if self .core is True :
318
+ message = self .create_message (stac_type , "core" )
319
+ self .core_validator (stac_type )
320
+ message ["schema" ] = [self .custom ]
321
+ self .valid = True
322
+ elif self .custom != "" :
323
+ message = self .create_message (stac_type , "custom" )
324
+ message ["schema" ] = [self .custom ]
325
+ self .custom_validator ()
326
+ self .valid = True
327
+ elif self .recursive :
328
+ self .valid = self .recursive_validator (stac_type )
329
+ elif self .extensions is True :
330
+ message = self .extensions_validator (stac_type )
296
331
else :
297
- cls .valid = True
298
- message = cls .default_validator (stac_type )
332
+ self .valid = True
333
+ message = self .default_validator (stac_type )
299
334
300
335
except URLError as e :
301
- message .update (cls .create_err_msg ("URLError" , str (e )))
336
+ message .update (self .create_err_msg ("URLError" , str (e )))
302
337
except JSONDecodeError as e :
303
- message .update (cls .create_err_msg ("JSONDecodeError" , str (e )))
338
+ message .update (self .create_err_msg ("JSONDecodeError" , str (e )))
304
339
except ValueError as e :
305
- message .update (cls .create_err_msg ("ValueError" , str (e )))
340
+ message .update (self .create_err_msg ("ValueError" , str (e )))
306
341
except TypeError as e :
307
- message .update (cls .create_err_msg ("TypeError" , str (e )))
342
+ message .update (self .create_err_msg ("TypeError" , str (e )))
308
343
except FileNotFoundError as e :
309
- message .update (cls .create_err_msg ("FileNotFoundError" , str (e )))
344
+ message .update (self .create_err_msg ("FileNotFoundError" , str (e )))
310
345
except ConnectionError as e :
311
- message .update (cls .create_err_msg ("ConnectionError" , str (e )))
346
+ message .update (self .create_err_msg ("ConnectionError" , str (e )))
312
347
except exceptions .SSLError as e :
313
- message .update (cls .create_err_msg ("SSLError" , str (e )))
348
+ message .update (self .create_err_msg ("SSLError" , str (e )))
314
349
except OSError as e :
315
- message .update (cls .create_err_msg ("OSError" , str (e )))
350
+ message .update (self .create_err_msg ("OSError" , str (e )))
316
351
except jsonschema .exceptions .ValidationError as e :
317
352
if e .absolute_path :
318
353
err_msg = f"{ e .message } . Error is in { ' -> ' .join ([str (i ) for i in e .absolute_path ])} "
319
354
else :
320
355
err_msg = f"{ e .message } of the root of the STAC object"
321
- message .update (cls .create_err_msg ("JSONSchemaValidationError" , err_msg ))
356
+ message .update (self .create_err_msg ("JSONSchemaValidationError" , err_msg ))
322
357
except KeyError as e :
323
- message .update (cls .create_err_msg ("KeyError" , str (e )))
358
+ message .update (self .create_err_msg ("KeyError" , str (e )))
324
359
except HTTPError as e :
325
- message .update (cls .create_err_msg ("HTTPError" , str (e )))
360
+ message .update (self .create_err_msg ("HTTPError" , str (e )))
326
361
except Exception as e :
327
- message .update (cls .create_err_msg ("Exception" , str (e )))
362
+ message .update (self .create_err_msg ("Exception" , str (e )))
328
363
329
364
if len (message ) > 0 :
330
- message ["valid_stac" ] = cls .valid
331
- cls .message .append (message )
365
+ message ["valid_stac" ] = self .valid
366
+ self .message .append (message )
332
367
333
- if cls .log != "" :
334
- f = open (cls .log , "w" )
335
- f .write (json .dumps (cls .message , indent = 4 ))
368
+ if self .log != "" :
369
+ f = open (self .log , "w" )
370
+ f .write (json .dumps (self .message , indent = 4 ))
336
371
f .close ()
337
372
338
- if cls .valid :
373
+ if self .valid :
339
374
return True
340
375
else :
341
376
return False
0 commit comments