-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathgather_stac_collections.py
More file actions
142 lines (118 loc) · 4.03 KB
/
Copy pathgather_stac_collections.py
File metadata and controls
142 lines (118 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import argparse
import json
import logging
import pathlib
from dataclasses import dataclass
from lib import stac
# Create a module logger into scope so that functions can use it
# Configure in main()
logger = logging.getLogger(__name__)
@dataclass
class ScriptArgs:
aws_mirror_dir: pathlib.Path
output: pathlib.Path
overwrite: bool
verbose: bool
dryrun: bool
@classmethod
def parse(cls):
parser = argparse.ArgumentParser(
description="Gather STAC Collections from the AWS STAC tree mirror and \
write an pgstac-ingest-ready NDJSON file."
)
#### Always required flags
parser.add_argument(
'--aws-mirror-dir',
required=True,
type=pathlib.Path,
help="Directory containing the root of the aws mirror of the STAC tree [required]"
)
parser.add_argument(
'--output',
required=True,
type=pathlib.Path,
help="Path to write NDJSON result [required]"
)
#### Extra CLI stuff
parser.add_argument(
"--overwrite",
help="Replace existing files when encountered",
action="store_true",
default=False,
)
parser.add_argument(
"-v",
"--verbose",
help="Verbose output",
action="store_true",
default=False,
)
parser.add_argument(
"--dryrun",
action="store_true",
default=False,
help="Preform export process without making any filesystem changes",
)
args = parser.parse_args()
return cls(**vars(args))
def validate(self):
if not self.aws_mirror_dir.exists():
raise FileNotFoundError(
f"The path provided for --aws-mirror-dir does not exist: {self.aws_mirror_dir}"
)
if not self.aws_mirror_dir.is_dir():
raise NotADirectoryError(
f"The path provided for --aws-mirror-dir must be a directory: {self.aws_mirror_dir}"
)
if not self.overwrite and self.output.exists():
raise FileExistsError(
"Output file already exists. Provide --overwrite flag to replace it."
)
return self
def main() -> None:
# Configure default script logging
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter(fmt="%(asctime)s %(levelname)s- %(message)s",
datefmt="%m-%d-%Y %H:%M:%S")
)
logger.addHandler(handler)
# Parse and verify arguments
try:
args = ScriptArgs.parse().validate()
except (FileNotFoundError, NotADirectoryError, FileExistsError, ValueError) as e:
logger.error(e)
exit(1)
if args.verbose:
logger.setLevel(logging.DEBUG)
logger.debug(f"Parsed arguments: {args}")
gather_stac_collections(args)
def gather_stac_collections(args: ScriptArgs):
logger.info("Building paths to collection files")
json_paths = set()
for collection_id in stac.COLLECTIONS:
domain, kind, version, resolution = collection_id.split("-")
json_paths.add(
args.aws_mirror_dir / domain / kind / version / f"{resolution}.json"
)
for path in json_paths:
if not path.exists():
raise FileNotFoundError(f"{path} does not exist.")
logger.debug(f"Found {path}")
logger.info(f"Found all {len(json_paths)} expected files")
logger.info("Parsing json and stripping 'links' section")
collections = []
for path in json_paths:
with open(path, "r") as f:
collection = json.load(f)
collection["links"] = []
collections.append(collection)
logger.info(f"Writing {args.output}")
if args.dryrun:
return
with open(args.output, "w") as f:
for collection in collections:
f.write(f"{json.dumps(collection, indent=None)}\n")
if __name__ == "__main__":
main()