3
3
4
4
import yaml
5
5
import json
6
+ import requests
6
7
8
+ from abc import ABC , abstractmethod
7
9
from collections import defaultdict
8
10
from dataclasses import dataclass , field , fields , is_dataclass , asdict
9
11
from functools import reduce
@@ -47,6 +49,46 @@ class DocGenMergeWarning(MetadataError):
47
49
pass
48
50
49
51
52
+ class ConfigLoader (ABC ):
53
+ @abstractmethod
54
+ def load (self , filename : str ) -> Tuple [Path , Any ]:
55
+ pass
56
+
57
+
58
+ class NoneLoader (ConfigLoader ):
59
+ def load (self , filename : str ) -> Tuple [Path , Any ]:
60
+ return Path (filename ), yaml .safe_load ("" )
61
+
62
+
63
+ class FileLoader (ConfigLoader ):
64
+ def __init__ (self , root : Optional [Path ] = None ):
65
+ self .config = root or Path (__file__ ).parent / "config"
66
+
67
+ def load (self , filename : str ) -> Tuple [Path , Any ]:
68
+ path = self .config / filename
69
+ print (f"Opening { path } " )
70
+ with path .open (encoding = "utf-8" ) as file :
71
+ return path , yaml .safe_load (file )
72
+
73
+
74
+ class GitHubLoader (ConfigLoader ):
75
+ def __init__ (self , repo : Optional [str ] = None , commit : Optional [str ] = None ):
76
+ self .repo = repo or "awsdocs/aws-doc-sdk-examples-tools"
77
+ self .commit = (
78
+ commit or "refs/heads/main"
79
+ ) # or refs/tags/2025.07.0 or a specific SHA
80
+ self .path = f"{ self .repo } /{ self .commit } /aws_doc_sdk_examples_tools/config"
81
+
82
+ def load (self , filename : str ) -> Tuple [Path , Any ]:
83
+ path = f"{ self .path } /{ filename } "
84
+ url = f"https://raw.githubusercontent.com/{ path } "
85
+ print (f"Requesting { url } " )
86
+ r = requests .get (url )
87
+ if r .status_code == 200 :
88
+ return Path (path ), yaml .safe_load (r .text )
89
+ raise Exception (f"Failed to request { url } ({ r .status_code } { r .text } )" )
90
+
91
+
50
92
@dataclass
51
93
class DocGen :
52
94
root : Path
@@ -170,7 +212,9 @@ def empty(cls, validation: ValidationConfig = ValidationConfig()) -> "DocGen":
170
212
171
213
@classmethod
172
214
def default (cls ) -> "DocGen" :
173
- return DocGen .empty ().for_root (Path (__file__ ).parent , incremental = True )
215
+ return DocGen .empty ().for_root (
216
+ Path (__file__ ).parent , GitHubLoader (), incremental = True
217
+ )
174
218
175
219
def clone (self ) -> "DocGen" :
176
220
return DocGen (
@@ -186,13 +230,9 @@ def clone(self) -> "DocGen":
186
230
examples = {},
187
231
)
188
232
189
- def for_root (
190
- self , root : Path , config : Optional [Path ] = None , incremental = False
191
- ) -> "DocGen" :
233
+ def for_root (self , root : Path , loader : ConfigLoader , incremental = False ) -> "DocGen" :
192
234
self .root = root
193
235
194
- config = config or Path (__file__ ).parent / "config"
195
-
196
236
try :
197
237
with open (root / ".doc_gen" / "validation.yaml" , encoding = "utf-8" ) as file :
198
238
validation = yaml .safe_load (file )
@@ -203,46 +243,37 @@ def for_root(
203
243
pass
204
244
205
245
try :
206
- sdk_path = config / "sdks.yaml"
207
- with sdk_path .open (encoding = "utf-8" ) as file :
208
- meta = yaml .safe_load (file )
209
- sdks , errs = parse_sdks (sdk_path , meta )
210
- self .sdks = sdks
211
- self .errors .extend (errs )
246
+ sdk_path , meta = loader .load ("sdks.yaml" )
247
+ sdks , errs = parse_sdks (sdk_path , meta )
248
+ self .sdks = sdks
249
+ self .errors .extend (errs )
212
250
except Exception :
213
251
pass
214
252
215
253
try :
216
- services_path = config / "services.yaml"
217
- with services_path .open (encoding = "utf-8" ) as file :
218
- meta = yaml .safe_load (file )
219
- services , service_errors = parse_services (services_path , meta )
220
- self .services = services
221
- for service in self .services .values ():
222
- if service .expanded :
223
- self .entities [service .long ] = service .expanded .long
224
- self .entities [service .short ] = service .expanded .short
225
- self .errors .extend (service_errors )
254
+ services_path , meta = loader .load ("services.yaml" )
255
+ services , service_errors = parse_services (services_path , meta )
256
+
257
+ self .services = services
258
+ for service in self .services .values ():
259
+ if service .expanded :
260
+ self .entities [service .long ] = service .expanded .long
261
+ self .entities [service .short ] = service .expanded .short
262
+ self .errors .extend (service_errors )
226
263
except Exception :
227
264
pass
228
265
229
266
try :
230
- categories_path = config / "categories.yaml"
231
- with categories_path .open (encoding = "utf-8" ) as file :
232
- meta = yaml .safe_load (file )
233
- standard_categories , categories , errs = parse_categories (
234
- categories_path , meta
235
- )
236
- self .standard_categories = standard_categories
237
- self .categories = categories
238
- self .errors .extend (errs )
267
+ path , meta = loader .load ("categories.yaml" )
268
+ standard_categories , categories , errs = parse_categories (path , meta )
269
+ self .standard_categories = standard_categories
270
+ self .categories = categories
271
+ self .errors .extend (errs )
239
272
except Exception :
240
273
pass
241
274
242
275
try :
243
- entities_config_path = config / "entities.yaml"
244
- with entities_config_path .open (encoding = "utf-8" ) as file :
245
- entities_config = yaml .safe_load (file )
276
+ path , entities_config = loader .load ("entities.yaml" )
246
277
for entity , expanded in entities_config ["expanded_override" ].items ():
247
278
self .entities [entity ] = expanded
248
279
except Exception :
@@ -294,12 +325,13 @@ def process_metadata(self, path: Path) -> "DocGen":
294
325
def from_root (
295
326
cls ,
296
327
root : Path ,
297
- config : Optional [Path ] = None ,
328
+ loader : Optional [ConfigLoader ] = None ,
298
329
validation : ValidationConfig = ValidationConfig (),
299
330
incremental : bool = False ,
300
331
) -> "DocGen" :
332
+ loader = loader or GitHubLoader ()
301
333
return DocGen .empty (validation = validation ).for_root (
302
- root , config , incremental = incremental
334
+ root , loader , incremental = incremental
303
335
)
304
336
305
337
def validate (self ):
0 commit comments