-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgenerate_dynamo_data.py
More file actions
126 lines (101 loc) · 4.23 KB
/
generate_dynamo_data.py
File metadata and controls
126 lines (101 loc) · 4.23 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
import json
import logging
import os
import re
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any
# Constants
OUTPUT_ROOT = "out"
DATE_FORMAT = "%Y%m%d"
VAR_PATTERN = re.compile(r"<<([^<>]+)>>")
# Configure logging
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
class DateVariableResolver:
"""Handles the logic for parsing and evaluating date-based variables."""
def __init__(self, today: datetime = None):
self.today = today or datetime.today()
def resolve(self, token: str) -> str:
logging.debug(f"Resolving variable: {token}")
parts = token.split("_")
if len(parts) < 3 or parts[0].upper() != "DATE":
raise ValueError(f"Unsupported variable format: {token}")
_, unit, value = parts[0], parts[1].lower(), parts[2]
try:
offset = int(value)
except ValueError:
raise ValueError(f"Invalid offset value: {value}")
if unit == "day":
return (self.today + timedelta(days=offset)).strftime(DATE_FORMAT)
if unit == "week":
return (self.today + timedelta(weeks=offset)).strftime(DATE_FORMAT)
if unit == "year":
return (self.today.replace(year=self.today.year + offset)).strftime(DATE_FORMAT)
if unit == "age":
try:
birth_date = self.today.replace(year=self.today.year - offset)
except ValueError:
# Handle February 29th
birth_date = self.today.replace(month=2, day=28, year=self.today.year - offset)
return birth_date.strftime(DATE_FORMAT)
raise ValueError(f"Unsupported calculation unit: {unit}")
class JsonTestDataProcessor:
"""Processes JSON test files by resolving placeholders in 'data' arrays."""
def __init__(self, input_dir: Path, output_dir: Path, resolver: DateVariableResolver):
self.input_dir = input_dir
self.output_dir = output_dir
self.resolver = resolver
def resolve_placeholders(self, obj: Any) -> Any:
if isinstance(obj, dict):
return {k: self.resolve_placeholders(v) for k, v in obj.items()}
if isinstance(obj, list):
return [self.resolve_placeholders(item) for item in obj]
if isinstance(obj, str):
return VAR_PATTERN.sub(self._replace_token, obj)
return obj
def _replace_token(self, match: re.Match) -> str:
token = match.group(1)
try:
return self.resolver.resolve(token)
except Exception as e:
logging.warning(f"Failed to resolve variable {token}: {e}")
return match.group(0)
def process_file(self, file_path: Path):
logging.info(f"Processing file: {file_path}")
try:
with open(file_path) as f:
content = json.load(f)
except Exception as e:
logging.exception(f"Failed to read {file_path}: {e}")
return
try:
resolved = self.resolve_placeholders(content)
except Exception as e:
logging.exception(f"Failed to resolve placeholders: {e}")
return
if "data" not in resolved:
logging.error(f"Missing 'data' key in {file_path}")
return
relative_path = file_path.relative_to(self.input_dir)
output_path = self.output_dir / relative_path
output_path.parent.mkdir(parents=True, exist_ok=True)
try:
with open(output_path, "w") as f:
json.dump(resolved["data"], f, indent=2)
logging.info(f"Written resolved file: {output_path}")
except Exception as e:
logging.exception(f"Failed to write output: {e}")
def main():
input_dir = Path()
output_dir = Path(OUTPUT_ROOT)
resolver = DateVariableResolver()
processor = JsonTestDataProcessor(input_dir, output_dir, resolver)
logging.info(f"Scanning for JSON files in {input_dir}")
for root, _, files in os.walk(input_dir):
for file in files:
if file.endswith(".json"):
processor.process_file(Path(root) / file)
else:
logging.debug(f"Skipping non-JSON file: {file}")
if __name__ == "__main__":
main()