Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/boto3/docs/resource.py: 17%
199 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
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
15from botocore import xform_name
16from botocore.docs.bcdoc.restdoc import DocumentStructure
17from botocore.docs.utils import get_official_service_name
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
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'
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)
58 def _add_title(self, section):
59 title_section = section.add_new_section('title')
60 title_section.style.h2(self._resource_name)
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)
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 )
75 # Add as short description about the resource
76 description_section = start_class.add_new_section('description')
77 self._add_description(description_section)
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)
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)
88 end_class = section.add_new_section('end_class')
89 end_class.style.end_sphinx_py_class()
91 def _add_description(self, section):
92 official_service_name = get_official_service_name(self._service_model)
93 section.write(
94 'A resource representing an {} {}'.format(
95 official_service_name, self._resource_name
96 )
97 )
99 def _add_example(self, section, identifier_names):
100 section.style.start_codeblock()
101 section.style.new_line()
102 section.write('import boto3')
103 section.style.new_line()
104 section.style.new_line()
105 section.write(
106 '{} = boto3.resource(\'{}\')'.format(
107 self._service_name, self._service_name
108 )
109 )
110 section.style.new_line()
111 example_values = get_identifier_values_for_example(identifier_names)
112 section.write(
113 '{} = {}.{}({})'.format(
114 xform_name(self._resource_name),
115 self._service_name,
116 self._resource_name,
117 example_values,
118 )
119 )
120 section.style.end_codeblock()
122 def _add_params_description(self, section, identifier_names):
123 for identifier_name in identifier_names:
124 description = get_identifier_description(
125 self._resource_name, identifier_name
126 )
127 section.write(f':type {identifier_name}: string')
128 section.style.new_line()
129 section.write(f':param {identifier_name}: {description}')
130 section.style.new_line()
132 def _add_overview_of_member_type(self, section, resource_member_type):
133 section.style.new_line()
134 section.write(
135 f'These are the resource\'s available {resource_member_type}:'
136 )
137 section.style.new_line()
138 section.style.toctree()
139 for member in self.member_map[resource_member_type]:
140 section.style.tocitem(f'{member}')
142 def _add_identifiers(self, section):
143 identifiers = self._resource.meta.resource_model.identifiers
144 section = section.add_new_section('identifiers')
145 member_list = []
146 if identifiers:
147 self.member_map['identifiers'] = member_list
148 add_resource_type_overview(
149 section=section,
150 resource_type='Identifiers',
151 description=(
152 'Identifiers are properties of a resource that are '
153 'set upon instantiation of the resource.'
154 ),
155 intro_link='identifiers_attributes_intro',
156 )
157 for identifier in identifiers:
158 member_list.append(identifier.name)
159 # Create a new DocumentStructure for each identifier and add contents.
160 identifier_doc = DocumentStructure(identifier.name, target='html')
161 breadcrumb_section = identifier_doc.add_new_section('breadcrumb')
162 breadcrumb_section.style.ref(self._resource_class_name, 'index')
163 breadcrumb_section.write(f' / Identifier / {identifier.name}')
164 identifier_doc.add_title_section(identifier.name)
165 identifier_section = identifier_doc.add_new_section(
166 identifier.name,
167 context={'qualifier': f'{self.class_name}.'},
168 )
169 document_identifier(
170 section=identifier_section,
171 resource_name=self._resource_name,
172 identifier_model=identifier,
173 )
174 # Write identifiers in individual/nested files.
175 # Path: <root>/reference/services/<service>/<resource_name>/<identifier_name>.rst
176 identifiers_dir_path = os.path.join(
177 self._root_docs_path,
178 f'{self._service_name}',
179 f'{self._resource_sub_path}',
180 )
181 identifier_doc.write_to_file(identifiers_dir_path, identifier.name)
183 if identifiers:
184 self._add_overview_of_member_type(section, 'identifiers')
186 def _add_attributes(self, section):
187 service_model = self._resource.meta.client.meta.service_model
188 attributes = {}
189 if self._resource.meta.resource_model.shape:
190 shape = service_model.shape_for(
191 self._resource.meta.resource_model.shape
192 )
193 attributes = self._resource.meta.resource_model.get_attributes(
194 shape
195 )
196 section = section.add_new_section('attributes')
197 attribute_list = []
198 if attributes:
199 add_resource_type_overview(
200 section=section,
201 resource_type='Attributes',
202 description=(
203 'Attributes provide access'
204 ' to the properties of a resource. Attributes are lazy-'
205 'loaded the first time one is accessed via the'
206 ' :py:meth:`load` method.'
207 ),
208 intro_link='identifiers_attributes_intro',
209 )
210 self.member_map['attributes'] = attribute_list
211 for attr_name in sorted(attributes):
212 _, attr_shape = attributes[attr_name]
213 attribute_list.append(attr_name)
214 # Create a new DocumentStructure for each attribute and add contents.
215 attribute_doc = DocumentStructure(attr_name, target='html')
216 breadcrumb_section = attribute_doc.add_new_section('breadcrumb')
217 breadcrumb_section.style.ref(self._resource_class_name, 'index')
218 breadcrumb_section.write(f' / Attribute / {attr_name}')
219 attribute_doc.add_title_section(attr_name)
220 attribute_section = attribute_doc.add_new_section(
221 attr_name,
222 context={'qualifier': f'{self.class_name}.'},
223 )
224 document_attribute(
225 section=attribute_section,
226 service_name=self._service_name,
227 resource_name=self._resource_name,
228 attr_name=attr_name,
229 event_emitter=self._resource.meta.client.meta.events,
230 attr_model=attr_shape,
231 )
232 # Write attributes in individual/nested files.
233 # Path: <root>/reference/services/<service>/<resource_name>/<attribute_name>.rst
234 attributes_dir_path = os.path.join(
235 self._root_docs_path,
236 f'{self._service_name}',
237 f'{self._resource_sub_path}',
238 )
239 attribute_doc.write_to_file(attributes_dir_path, attr_name)
240 if attributes:
241 self._add_overview_of_member_type(section, 'attributes')
243 def _add_references(self, section):
244 section = section.add_new_section('references')
245 references = self._resource.meta.resource_model.references
246 reference_list = []
247 if references:
248 add_resource_type_overview(
249 section=section,
250 resource_type='References',
251 description=(
252 'References are related resource instances that have '
253 'a belongs-to relationship.'
254 ),
255 intro_link='references_intro',
256 )
257 self.member_map['references'] = reference_list
258 self._add_overview_of_member_type(section, 'references')
259 for reference in references:
260 reference_list.append(reference.name)
261 # Create a new DocumentStructure for each reference and add contents.
262 reference_doc = DocumentStructure(reference.name, target='html')
263 breadcrumb_section = reference_doc.add_new_section('breadcrumb')
264 breadcrumb_section.style.ref(self._resource_class_name, 'index')
265 breadcrumb_section.write(f' / Reference / {reference.name}')
266 reference_doc.add_title_section(reference.name)
267 reference_section = reference_doc.add_new_section(
268 reference.name,
269 context={'qualifier': f'{self.class_name}.'},
270 )
271 document_reference(
272 section=reference_section,
273 reference_model=reference,
274 )
275 # Write references in individual/nested files.
276 # Path: <root>/reference/services/<service>/<resource_name>/<reference_name>.rst
277 references_dir_path = os.path.join(
278 self._root_docs_path,
279 f'{self._service_name}',
280 f'{self._resource_sub_path}',
281 )
282 reference_doc.write_to_file(references_dir_path, reference.name)
283 if references:
284 self._add_overview_of_member_type(section, 'references')
286 def _add_actions(self, section):
287 section = section.add_new_section('actions')
288 actions = self._resource.meta.resource_model.actions
289 if actions:
290 documenter = ActionDocumenter(self._resource, self._root_docs_path)
291 documenter.member_map = self.member_map
292 documenter.document_actions(section)
293 self._add_overview_of_member_type(section, 'actions')
295 def _add_sub_resources(self, section):
296 section = section.add_new_section('sub-resources')
297 sub_resources = self._resource.meta.resource_model.subresources
298 if sub_resources:
299 documenter = SubResourceDocumenter(
300 self._resource, self._root_docs_path
301 )
302 documenter.member_map = self.member_map
303 documenter.document_sub_resources(section)
304 self._add_overview_of_member_type(section, 'sub-resources')
306 def _add_collections(self, section):
307 section = section.add_new_section('collections')
308 collections = self._resource.meta.resource_model.collections
309 if collections:
310 documenter = CollectionDocumenter(
311 self._resource, self._root_docs_path
312 )
313 documenter.member_map = self.member_map
314 documenter.document_collections(section)
315 self._add_overview_of_member_type(section, 'collections')
317 def _add_waiters(self, section):
318 section = section.add_new_section('waiters')
319 waiters = self._resource.meta.resource_model.waiters
320 if waiters:
321 service_waiter_model = self._botocore_session.get_waiter_model(
322 self._service_name
323 )
324 documenter = WaiterResourceDocumenter(
325 self._resource, service_waiter_model, self._root_docs_path
326 )
327 documenter.member_map = self.member_map
328 documenter.document_resource_waiters(section)
329 self._add_overview_of_member_type(section, 'waiters')
331 def _add_resource_note(self, section):
332 section = section.add_new_section('feature-freeze')
333 section.style.start_note()
334 section.write(
335 "Before using anything on this page, please refer to the resources "
336 ":doc:`user guide <../../../../guide/resources>` for the most recent "
337 "guidance on using resources."
338 )
339 section.style.end_note()
342class ServiceResourceDocumenter(ResourceDocumenter):
343 @property
344 def class_name(self):
345 return f'{self._service_docs_name}.ServiceResource'
347 def _add_title(self, section):
348 title_section = section.add_new_section('title')
349 title_section.style.h2('Service Resource')
351 def _add_description(self, section):
352 official_service_name = get_official_service_name(self._service_model)
353 section.write(f'A resource representing {official_service_name}')
355 def _add_example(self, section, identifier_names):
356 section.style.start_codeblock()
357 section.style.new_line()
358 section.write('import boto3')
359 section.style.new_line()
360 section.style.new_line()
361 section.write(
362 f'{self._service_name} = boto3.resource(\'{self._service_name}\')'
363 )
364 section.style.end_codeblock()