Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/boto3/docs/resource.py: 17%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

198 statements  

1# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"). You 

4# may not use this file except in compliance with the License. A copy of 

5# the License is located at 

6# 

7# https://aws.amazon.com/apache2.0/ 

8# 

9# or in the "license" file accompanying this file. This file is 

10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

11# ANY KIND, either express or implied. See the License for the specific 

12# language governing permissions and limitations under the License. 

13import os 

14 

15from botocore import xform_name 

16from botocore.docs.bcdoc.restdoc import DocumentStructure 

17from botocore.docs.utils import get_official_service_name 

18 

19from boto3.docs.action import ActionDocumenter 

20from boto3.docs.attr import ( 

21 document_attribute, 

22 document_identifier, 

23 document_reference, 

24) 

25from boto3.docs.base import BaseDocumenter 

26from boto3.docs.collection import CollectionDocumenter 

27from boto3.docs.subresource import SubResourceDocumenter 

28from boto3.docs.utils import ( 

29 add_resource_type_overview, 

30 get_identifier_args_for_signature, 

31 get_identifier_description, 

32 get_identifier_values_for_example, 

33) 

34from boto3.docs.waiter import WaiterResourceDocumenter 

35 

36 

37class ResourceDocumenter(BaseDocumenter): 

38 def __init__(self, resource, botocore_session, root_docs_path): 

39 super().__init__(resource) 

40 self._botocore_session = botocore_session 

41 self._root_docs_path = root_docs_path 

42 self._resource_sub_path = self._resource_name.lower() 

43 if self._resource_name == self._service_name: 

44 self._resource_sub_path = 'service-resource' 

45 

46 def document_resource(self, section): 

47 self._add_title(section) 

48 self._add_resource_note(section) 

49 self._add_intro(section) 

50 self._add_identifiers(section) 

51 self._add_attributes(section) 

52 self._add_references(section) 

53 self._add_actions(section) 

54 self._add_sub_resources(section) 

55 self._add_collections(section) 

56 self._add_waiters(section) 

57 

58 def _add_title(self, section): 

59 title_section = section.add_new_section('title') 

60 title_section.style.h2(self._resource_name) 

61 

62 def _add_intro(self, section): 

63 identifier_names = [] 

64 if self._resource_model.identifiers: 

65 for identifier in self._resource_model.identifiers: 

66 identifier_names.append(identifier.name) 

67 

68 # Write out the class signature. 

69 class_args = get_identifier_args_for_signature(identifier_names) 

70 start_class = section.add_new_section('start_class') 

71 start_class.style.start_sphinx_py_class( 

72 class_name=f'{self.class_name}({class_args})' 

73 ) 

74 

75 # Add as short description about the resource 

76 description_section = start_class.add_new_section('description') 

77 self._add_description(description_section) 

78 

79 # Add an example of how to instantiate the resource 

80 example_section = start_class.add_new_section('example') 

81 self._add_example(example_section, identifier_names) 

82 

83 # Add the description for the parameters to instantiate the 

84 # resource. 

85 param_section = start_class.add_new_section('params') 

86 self._add_params_description(param_section, identifier_names) 

87 

88 end_class = section.add_new_section('end_class') 

89 end_class.style.end_sphinx_py_class() 

90 

91 def _add_description(self, section): 

92 official_service_name = get_official_service_name(self._service_model) 

93 section.write( 

94 f'A resource representing an {official_service_name} {self._resource_name}' 

95 ) 

96 

97 def _add_example(self, section, identifier_names): 

98 section.style.start_codeblock() 

99 section.style.new_line() 

100 section.write('import boto3') 

101 section.style.new_line() 

102 section.style.new_line() 

103 section.write( 

104 f'{self._service_name} = boto3.resource(\'{self._service_name}\')' 

105 ) 

106 section.style.new_line() 

107 example_values = get_identifier_values_for_example(identifier_names) 

108 section.write( 

109 f'{xform_name(self._resource_name)} = {self._service_name}.{self._resource_name}({example_values})' 

110 ) 

111 section.style.end_codeblock() 

112 

113 def _add_params_description(self, section, identifier_names): 

114 for identifier_name in identifier_names: 

115 description = get_identifier_description( 

116 self._resource_name, identifier_name 

117 ) 

118 section.write(f':type {identifier_name}: string') 

119 section.style.new_line() 

120 section.write(f':param {identifier_name}: {description}') 

121 section.style.new_line() 

122 

123 def _add_overview_of_member_type(self, section, resource_member_type): 

124 section.style.new_line() 

125 section.write( 

126 f'These are the resource\'s available {resource_member_type}:' 

127 ) 

128 section.style.new_line() 

129 section.style.toctree() 

130 for member in self.member_map[resource_member_type]: 

131 section.style.tocitem(f'{member}') 

132 

133 def _add_identifiers(self, section): 

134 identifiers = self._resource.meta.resource_model.identifiers 

135 section = section.add_new_section('identifiers') 

136 member_list = [] 

137 if identifiers: 

138 self.member_map['identifiers'] = member_list 

139 add_resource_type_overview( 

140 section=section, 

141 resource_type='Identifiers', 

142 description=( 

143 'Identifiers are properties of a resource that are ' 

144 'set upon instantiation of the resource.' 

145 ), 

146 intro_link='identifiers_attributes_intro', 

147 ) 

148 for identifier in identifiers: 

149 member_list.append(identifier.name) 

150 # Create a new DocumentStructure for each identifier and add contents. 

151 identifier_doc = DocumentStructure(identifier.name, target='html') 

152 breadcrumb_section = identifier_doc.add_new_section('breadcrumb') 

153 breadcrumb_section.style.ref(self._resource_class_name, 'index') 

154 breadcrumb_section.write(f' / Identifier / {identifier.name}') 

155 identifier_doc.add_title_section(identifier.name) 

156 identifier_section = identifier_doc.add_new_section( 

157 identifier.name, 

158 context={'qualifier': f'{self.class_name}.'}, 

159 ) 

160 document_identifier( 

161 section=identifier_section, 

162 resource_name=self._resource_name, 

163 identifier_model=identifier, 

164 ) 

165 # Write identifiers in individual/nested files. 

166 # Path: <root>/reference/services/<service>/<resource_name>/<identifier_name>.rst 

167 identifiers_dir_path = os.path.join( 

168 self._root_docs_path, 

169 f'{self._service_name}', 

170 f'{self._resource_sub_path}', 

171 ) 

172 identifier_doc.write_to_file(identifiers_dir_path, identifier.name) 

173 

174 if identifiers: 

175 self._add_overview_of_member_type(section, 'identifiers') 

176 

177 def _add_attributes(self, section): 

178 service_model = self._resource.meta.client.meta.service_model 

179 attributes = {} 

180 if self._resource.meta.resource_model.shape: 

181 shape = service_model.shape_for( 

182 self._resource.meta.resource_model.shape 

183 ) 

184 attributes = self._resource.meta.resource_model.get_attributes( 

185 shape 

186 ) 

187 section = section.add_new_section('attributes') 

188 attribute_list = [] 

189 if attributes: 

190 add_resource_type_overview( 

191 section=section, 

192 resource_type='Attributes', 

193 description=( 

194 'Attributes provide access' 

195 ' to the properties of a resource. Attributes are lazy-' 

196 'loaded the first time one is accessed via the' 

197 ' :py:meth:`load` method.' 

198 ), 

199 intro_link='identifiers_attributes_intro', 

200 ) 

201 self.member_map['attributes'] = attribute_list 

202 for attr_name in sorted(attributes): 

203 _, attr_shape = attributes[attr_name] 

204 attribute_list.append(attr_name) 

205 # Create a new DocumentStructure for each attribute and add contents. 

206 attribute_doc = DocumentStructure(attr_name, target='html') 

207 breadcrumb_section = attribute_doc.add_new_section('breadcrumb') 

208 breadcrumb_section.style.ref(self._resource_class_name, 'index') 

209 breadcrumb_section.write(f' / Attribute / {attr_name}') 

210 attribute_doc.add_title_section(attr_name) 

211 attribute_section = attribute_doc.add_new_section( 

212 attr_name, 

213 context={'qualifier': f'{self.class_name}.'}, 

214 ) 

215 document_attribute( 

216 section=attribute_section, 

217 service_name=self._service_name, 

218 resource_name=self._resource_name, 

219 attr_name=attr_name, 

220 event_emitter=self._resource.meta.client.meta.events, 

221 attr_model=attr_shape, 

222 ) 

223 # Write attributes in individual/nested files. 

224 # Path: <root>/reference/services/<service>/<resource_name>/<attribute_name>.rst 

225 attributes_dir_path = os.path.join( 

226 self._root_docs_path, 

227 f'{self._service_name}', 

228 f'{self._resource_sub_path}', 

229 ) 

230 attribute_doc.write_to_file(attributes_dir_path, attr_name) 

231 if attributes: 

232 self._add_overview_of_member_type(section, 'attributes') 

233 

234 def _add_references(self, section): 

235 section = section.add_new_section('references') 

236 references = self._resource.meta.resource_model.references 

237 reference_list = [] 

238 if references: 

239 add_resource_type_overview( 

240 section=section, 

241 resource_type='References', 

242 description=( 

243 'References are related resource instances that have ' 

244 'a belongs-to relationship.' 

245 ), 

246 intro_link='references_intro', 

247 ) 

248 self.member_map['references'] = reference_list 

249 for reference in references: 

250 reference_list.append(reference.name) 

251 # Create a new DocumentStructure for each reference and add contents. 

252 reference_doc = DocumentStructure(reference.name, target='html') 

253 breadcrumb_section = reference_doc.add_new_section('breadcrumb') 

254 breadcrumb_section.style.ref(self._resource_class_name, 'index') 

255 breadcrumb_section.write(f' / Reference / {reference.name}') 

256 reference_doc.add_title_section(reference.name) 

257 reference_section = reference_doc.add_new_section( 

258 reference.name, 

259 context={'qualifier': f'{self.class_name}.'}, 

260 ) 

261 document_reference( 

262 section=reference_section, 

263 reference_model=reference, 

264 ) 

265 # Write references in individual/nested files. 

266 # Path: <root>/reference/services/<service>/<resource_name>/<reference_name>.rst 

267 references_dir_path = os.path.join( 

268 self._root_docs_path, 

269 f'{self._service_name}', 

270 f'{self._resource_sub_path}', 

271 ) 

272 reference_doc.write_to_file(references_dir_path, reference.name) 

273 if references: 

274 self._add_overview_of_member_type(section, 'references') 

275 

276 def _add_actions(self, section): 

277 section = section.add_new_section('actions') 

278 actions = self._resource.meta.resource_model.actions 

279 if actions: 

280 documenter = ActionDocumenter(self._resource, self._root_docs_path) 

281 documenter.member_map = self.member_map 

282 documenter.document_actions(section) 

283 self._add_overview_of_member_type(section, 'actions') 

284 

285 def _add_sub_resources(self, section): 

286 section = section.add_new_section('sub-resources') 

287 sub_resources = self._resource.meta.resource_model.subresources 

288 if sub_resources: 

289 documenter = SubResourceDocumenter( 

290 self._resource, self._root_docs_path 

291 ) 

292 documenter.member_map = self.member_map 

293 documenter.document_sub_resources(section) 

294 self._add_overview_of_member_type(section, 'sub-resources') 

295 

296 def _add_collections(self, section): 

297 section = section.add_new_section('collections') 

298 collections = self._resource.meta.resource_model.collections 

299 if collections: 

300 documenter = CollectionDocumenter( 

301 self._resource, self._root_docs_path 

302 ) 

303 documenter.member_map = self.member_map 

304 documenter.document_collections(section) 

305 self._add_overview_of_member_type(section, 'collections') 

306 

307 def _add_waiters(self, section): 

308 section = section.add_new_section('waiters') 

309 waiters = self._resource.meta.resource_model.waiters 

310 if waiters: 

311 service_waiter_model = self._botocore_session.get_waiter_model( 

312 self._service_name 

313 ) 

314 documenter = WaiterResourceDocumenter( 

315 self._resource, service_waiter_model, self._root_docs_path 

316 ) 

317 documenter.member_map = self.member_map 

318 documenter.document_resource_waiters(section) 

319 self._add_overview_of_member_type(section, 'waiters') 

320 

321 def _add_resource_note(self, section): 

322 section = section.add_new_section('feature-freeze') 

323 section.style.start_note() 

324 section.write( 

325 "Before using anything on this page, please refer to the resources " 

326 ":doc:`user guide <../../../../guide/resources>` for the most recent " 

327 "guidance on using resources." 

328 ) 

329 section.style.end_note() 

330 

331 

332class ServiceResourceDocumenter(ResourceDocumenter): 

333 @property 

334 def class_name(self): 

335 return f'{self._service_docs_name}.ServiceResource' 

336 

337 def _add_title(self, section): 

338 title_section = section.add_new_section('title') 

339 title_section.style.h2('Service Resource') 

340 

341 def _add_description(self, section): 

342 official_service_name = get_official_service_name(self._service_model) 

343 section.write(f'A resource representing {official_service_name}') 

344 

345 def _add_example(self, section, identifier_names): 

346 section.style.start_codeblock() 

347 section.style.new_line() 

348 section.write('import boto3') 

349 section.style.new_line() 

350 section.style.new_line() 

351 section.write( 

352 f'{self._service_name} = boto3.resource(\'{self._service_name}\')' 

353 ) 

354 section.style.end_codeblock()