about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/boto3/docs
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/boto3/docs
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/boto3/docs')
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/__init__.py51
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/action.py214
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/attr.py72
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/base.py51
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/client.py24
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/collection.py291
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/docstring.py77
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/method.py77
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/resource.py354
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/service.py202
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/subresource.py145
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/utils.py146
-rw-r--r--.venv/lib/python3.12/site-packages/boto3/docs/waiter.py130
13 files changed, 1834 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/__init__.py b/.venv/lib/python3.12/site-packages/boto3/docs/__init__.py
new file mode 100644
index 00000000..d6ab12fa
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/__init__.py
@@ -0,0 +1,51 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore.docs import DEPRECATED_SERVICE_NAMES
+
+from boto3.docs.service import ServiceDocumenter
+
+
+def generate_docs(root_dir, session):
+    """Generates the reference documentation for botocore
+
+    This will go through every available AWS service and output ReSTructured
+    text files documenting each service.
+
+    :param root_dir: The directory to write the reference files to. Each
+        service's reference documentation is located at
+        root_dir/reference/services/service-name.rst
+
+    :param session: The boto3 session
+    """
+    services_doc_path = os.path.join(root_dir, 'reference', 'services')
+    if not os.path.exists(services_doc_path):
+        os.makedirs(services_doc_path)
+
+    # Prevents deprecated service names from being generated in docs.
+    available_services = [
+        service
+        for service in session.get_available_services()
+        if service not in DEPRECATED_SERVICE_NAMES
+    ]
+
+    for service_name in available_services:
+        docs = ServiceDocumenter(
+            service_name, session, services_doc_path
+        ).document_service()
+        service_doc_path = os.path.join(
+            services_doc_path, service_name + '.rst'
+        )
+        with open(service_doc_path, 'wb') as f:
+            f.write(docs)
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/action.py b/.venv/lib/python3.12/site-packages/boto3/docs/action.py
new file mode 100644
index 00000000..44a99083
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/action.py
@@ -0,0 +1,214 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import (
+    document_custom_method,
+    document_model_driven_method,
+)
+from botocore.model import OperationModel
+from botocore.utils import get_service_module_name
+
+from boto3.docs.base import NestedDocumenter
+from boto3.docs.method import document_model_driven_resource_method
+from boto3.docs.utils import (
+    add_resource_type_overview,
+    get_resource_ignore_params,
+    get_resource_public_actions,
+)
+
+PUT_DATA_WARNING_MESSAGE = """
+.. warning::
+    It is recommended to use the :py:meth:`put_metric_data`
+    :doc:`client method <../../cloudwatch/client/put_metric_data>`
+    instead. If you would still like to use this resource method,
+    please make sure that ``MetricData[].MetricName`` is equal to
+    the metric resource's ``name`` attribute.
+"""
+
+WARNING_MESSAGES = {
+    "Metric": {"put_data": PUT_DATA_WARNING_MESSAGE},
+}
+
+IGNORE_PARAMS = {"Metric": {"put_data": ["Namespace"]}}
+
+
+class ActionDocumenter(NestedDocumenter):
+    def document_actions(self, section):
+        modeled_actions_list = self._resource_model.actions
+        modeled_actions = {}
+        for modeled_action in modeled_actions_list:
+            modeled_actions[modeled_action.name] = modeled_action
+        resource_actions = get_resource_public_actions(
+            self._resource.__class__
+        )
+        self.member_map['actions'] = sorted(resource_actions)
+        add_resource_type_overview(
+            section=section,
+            resource_type='Actions',
+            description=(
+                'Actions call operations on resources.  They may '
+                'automatically handle the passing in of arguments set '
+                'from identifiers and some attributes.'
+            ),
+            intro_link='actions_intro',
+        )
+        resource_warnings = WARNING_MESSAGES.get(self._resource_name, {})
+        for action_name in sorted(resource_actions):
+            # Create a new DocumentStructure for each action and add contents.
+            action_doc = DocumentStructure(action_name, target='html')
+            breadcrumb_section = action_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Action / {action_name}')
+            action_doc.add_title_section(action_name)
+            warning_message = resource_warnings.get(action_name)
+            if warning_message is not None:
+                action_doc.add_new_section("warning").write(warning_message)
+            action_section = action_doc.add_new_section(
+                action_name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            if action_name in ['load', 'reload'] and self._resource_model.load:
+                document_load_reload_action(
+                    section=action_section,
+                    action_name=action_name,
+                    resource_name=self._resource_name,
+                    event_emitter=self._resource.meta.client.meta.events,
+                    load_model=self._resource_model.load,
+                    service_model=self._service_model,
+                )
+            elif action_name in modeled_actions:
+                document_action(
+                    section=action_section,
+                    resource_name=self._resource_name,
+                    event_emitter=self._resource.meta.client.meta.events,
+                    action_model=modeled_actions[action_name],
+                    service_model=self._service_model,
+                )
+            else:
+                document_custom_method(
+                    action_section, action_name, resource_actions[action_name]
+                )
+            # Write actions in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<action_name>.rst
+            actions_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            action_doc.write_to_file(actions_dir_path, action_name)
+
+
+def document_action(
+    section,
+    resource_name,
+    event_emitter,
+    action_model,
+    service_model,
+    include_signature=True,
+):
+    """Documents a resource action
+
+    :param section: The section to write to
+
+    :param resource_name: The name of the resource
+
+    :param event_emitter: The event emitter to use to emit events
+
+    :param action_model: The model of the action
+
+    :param service_model: The model of the service
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    operation_model = service_model.operation_model(
+        action_model.request.operation
+    )
+    ignore_params = IGNORE_PARAMS.get(resource_name, {}).get(
+        action_model.name,
+        get_resource_ignore_params(action_model.request.params),
+    )
+    example_return_value = 'response'
+    if action_model.resource:
+        example_return_value = xform_name(action_model.resource.type)
+    example_resource_name = xform_name(resource_name)
+    if service_model.service_name == resource_name:
+        example_resource_name = resource_name
+    example_prefix = (
+        f'{example_return_value} = {example_resource_name}.{action_model.name}'
+    )
+    full_action_name = (
+        f"{section.context.get('qualifier', '')}{action_model.name}"
+    )
+    document_model_driven_resource_method(
+        section=section,
+        method_name=full_action_name,
+        operation_model=operation_model,
+        event_emitter=event_emitter,
+        method_description=operation_model.documentation,
+        example_prefix=example_prefix,
+        exclude_input=ignore_params,
+        resource_action_model=action_model,
+        include_signature=include_signature,
+    )
+
+
+def document_load_reload_action(
+    section,
+    action_name,
+    resource_name,
+    event_emitter,
+    load_model,
+    service_model,
+    include_signature=True,
+):
+    """Documents the resource load action
+
+    :param section: The section to write to
+
+    :param action_name: The name of the loading action should be load or reload
+
+    :param resource_name: The name of the resource
+
+    :param event_emitter: The event emitter to use to emit events
+
+    :param load_model: The model of the load action
+
+    :param service_model: The model of the service
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    description = (
+        f'Calls :py:meth:`{get_service_module_name(service_model)}.Client.'
+        f'{xform_name(load_model.request.operation)}` to update the attributes of the '
+        f'{resource_name} resource. Note that the load and reload methods are '
+        'the same method and can be used interchangeably.'
+    )
+    example_resource_name = xform_name(resource_name)
+    if service_model.service_name == resource_name:
+        example_resource_name = resource_name
+    example_prefix = f'{example_resource_name}.{action_name}'
+    full_action_name = f"{section.context.get('qualifier', '')}{action_name}"
+    document_model_driven_method(
+        section=section,
+        method_name=full_action_name,
+        operation_model=OperationModel({}, service_model),
+        event_emitter=event_emitter,
+        method_description=description,
+        example_prefix=example_prefix,
+        include_signature=include_signature,
+    )
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/attr.py b/.venv/lib/python3.12/site-packages/boto3/docs/attr.py
new file mode 100644
index 00000000..a968da29
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/attr.py
@@ -0,0 +1,72 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.params import ResponseParamsDocumenter
+
+from boto3.docs.utils import get_identifier_description
+
+
+class ResourceShapeDocumenter(ResponseParamsDocumenter):
+    EVENT_NAME = 'resource-shape'
+
+
+def document_attribute(
+    section,
+    service_name,
+    resource_name,
+    attr_name,
+    event_emitter,
+    attr_model,
+    include_signature=True,
+):
+    if include_signature:
+        full_attr_name = f"{section.context.get('qualifier', '')}{attr_name}"
+        section.style.start_sphinx_py_attr(full_attr_name)
+    # Note that an attribute may have one, may have many, or may have no
+    # operations that back the resource's shape. So we just set the
+    # operation_name to the resource name if we ever to hook in and modify
+    # a particular attribute.
+    ResourceShapeDocumenter(
+        service_name=service_name,
+        operation_name=resource_name,
+        event_emitter=event_emitter,
+    ).document_params(section=section, shape=attr_model)
+
+
+def document_identifier(
+    section,
+    resource_name,
+    identifier_model,
+    include_signature=True,
+):
+    if include_signature:
+        full_identifier_name = (
+            f"{section.context.get('qualifier', '')}{identifier_model.name}"
+        )
+        section.style.start_sphinx_py_attr(full_identifier_name)
+    description = get_identifier_description(
+        resource_name, identifier_model.name
+    )
+    section.write(f'*(string)* {description}')
+
+
+def document_reference(section, reference_model, include_signature=True):
+    if include_signature:
+        full_reference_name = (
+            f"{section.context.get('qualifier', '')}{reference_model.name}"
+        )
+        section.style.start_sphinx_py_attr(full_reference_name)
+    reference_type = f'(:py:class:`{reference_model.resource.type}`) '
+    section.write(reference_type)
+    section.include_doc_string(
+        f'The related {reference_model.name} if set, otherwise ``None``.'
+    )
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/base.py b/.venv/lib/python3.12/site-packages/boto3/docs/base.py
new file mode 100644
index 00000000..ee496461
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/base.py
@@ -0,0 +1,51 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.compat import OrderedDict
+
+
+class BaseDocumenter:
+    def __init__(self, resource):
+        self._resource = resource
+        self._client = self._resource.meta.client
+        self._resource_model = self._resource.meta.resource_model
+        self._service_model = self._client.meta.service_model
+        self._resource_name = self._resource.meta.resource_model.name
+        self._service_name = self._service_model.service_name
+        self._service_docs_name = self._client.__class__.__name__
+        self.member_map = OrderedDict()
+        self.represents_service_resource = (
+            self._service_name == self._resource_name
+        )
+        self._resource_class_name = self._resource_name
+        if self._resource_name == self._service_name:
+            self._resource_class_name = 'ServiceResource'
+
+    @property
+    def class_name(self):
+        return f'{self._service_docs_name}.{self._resource_name}'
+
+
+class NestedDocumenter(BaseDocumenter):
+    def __init__(self, resource, root_docs_path):
+        super().__init__(resource)
+        self._root_docs_path = root_docs_path
+        self._resource_sub_path = self._resource_name.lower()
+        if self._resource_name == self._service_name:
+            self._resource_sub_path = 'service-resource'
+
+    @property
+    def class_name(self):
+        resource_class_name = self._resource_name
+        if self._resource_name == self._service_name:
+            resource_class_name = 'ServiceResource'
+        return f'{self._service_docs_name}.{resource_class_name}'
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/client.py b/.venv/lib/python3.12/site-packages/boto3/docs/client.py
new file mode 100644
index 00000000..b1990851
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/client.py
@@ -0,0 +1,24 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.client import ClientDocumenter
+
+
+class Boto3ClientDocumenter(ClientDocumenter):
+    def _add_client_creation_example(self, section):
+        section.style.start_codeblock()
+        section.style.new_line()
+        section.write('import boto3')
+        section.style.new_line()
+        section.style.new_line()
+        section.write(f'client = boto3.client(\'{self._service_name}\')')
+        section.style.end_codeblock()
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/collection.py b/.venv/lib/python3.12/site-packages/boto3/docs/collection.py
new file mode 100644
index 00000000..16108db8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/collection.py
@@ -0,0 +1,291 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import get_instance_public_methods
+from botocore.docs.utils import DocumentedShape
+
+from boto3.docs.base import NestedDocumenter
+from boto3.docs.method import document_model_driven_resource_method
+from boto3.docs.utils import (
+    add_resource_type_overview,
+    get_resource_ignore_params,
+)
+
+
+class CollectionDocumenter(NestedDocumenter):
+    def document_collections(self, section):
+        collections = self._resource.meta.resource_model.collections
+        collections_list = []
+        add_resource_type_overview(
+            section=section,
+            resource_type='Collections',
+            description=(
+                'Collections provide an interface to iterate over and '
+                'manipulate groups of resources. '
+            ),
+            intro_link='guide_collections',
+        )
+        self.member_map['collections'] = collections_list
+        for collection in collections:
+            collections_list.append(collection.name)
+            # Create a new DocumentStructure for each collection and add contents.
+            collection_doc = DocumentStructure(collection.name, target='html')
+            breadcrumb_section = collection_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Collection / {collection.name}')
+            collection_doc.add_title_section(collection.name)
+            collection_section = collection_doc.add_new_section(
+                collection.name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            self._document_collection(collection_section, collection)
+
+            # Write collections in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<collection_name>.rst
+            collections_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            collection_doc.write_to_file(collections_dir_path, collection.name)
+
+    def _document_collection(self, section, collection):
+        methods = get_instance_public_methods(
+            getattr(self._resource, collection.name)
+        )
+        document_collection_object(section, collection)
+        batch_actions = {}
+        for batch_action in collection.batch_actions:
+            batch_actions[batch_action.name] = batch_action
+
+        for method in sorted(methods):
+            method_section = section.add_new_section(method)
+            if method in batch_actions:
+                document_batch_action(
+                    section=method_section,
+                    resource_name=self._resource_name,
+                    event_emitter=self._resource.meta.client.meta.events,
+                    batch_action_model=batch_actions[method],
+                    collection_model=collection,
+                    service_model=self._resource.meta.client.meta.service_model,
+                )
+            else:
+                document_collection_method(
+                    section=method_section,
+                    resource_name=self._resource_name,
+                    action_name=method,
+                    event_emitter=self._resource.meta.client.meta.events,
+                    collection_model=collection,
+                    service_model=self._resource.meta.client.meta.service_model,
+                )
+
+
+def document_collection_object(
+    section,
+    collection_model,
+    include_signature=True,
+):
+    """Documents a collection resource object
+
+    :param section: The section to write to
+
+    :param collection_model: The model of the collection
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    if include_signature:
+        full_collection_name = (
+            f"{section.context.get('qualifier', '')}{collection_model.name}"
+        )
+        section.style.start_sphinx_py_attr(full_collection_name)
+    section.include_doc_string(
+        f'A collection of {collection_model.resource.type} resources.'
+    )
+    section.include_doc_string(
+        f'A {collection_model.resource.type} Collection will include all '
+        f'resources by default, and extreme caution should be taken when '
+        f'performing actions on all resources.'
+    )
+
+
+def document_batch_action(
+    section,
+    resource_name,
+    event_emitter,
+    batch_action_model,
+    service_model,
+    collection_model,
+    include_signature=True,
+):
+    """Documents a collection's batch action
+
+    :param section: The section to write to
+
+    :param resource_name: The name of the resource
+
+    :param action_name: The name of collection action. Currently only
+        can be all, filter, limit, or page_size
+
+    :param event_emitter: The event emitter to use to emit events
+
+    :param batch_action_model: The model of the batch action
+
+    :param collection_model: The model of the collection
+
+    :param service_model: The model of the service
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    operation_model = service_model.operation_model(
+        batch_action_model.request.operation
+    )
+    ignore_params = get_resource_ignore_params(
+        batch_action_model.request.params
+    )
+
+    example_return_value = 'response'
+    if batch_action_model.resource:
+        example_return_value = xform_name(batch_action_model.resource.type)
+
+    example_resource_name = xform_name(resource_name)
+    if service_model.service_name == resource_name:
+        example_resource_name = resource_name
+    example_prefix = f'{example_return_value} = {example_resource_name}.{collection_model.name}.{batch_action_model.name}'
+    document_model_driven_resource_method(
+        section=section,
+        method_name=batch_action_model.name,
+        operation_model=operation_model,
+        event_emitter=event_emitter,
+        method_description=operation_model.documentation,
+        example_prefix=example_prefix,
+        exclude_input=ignore_params,
+        resource_action_model=batch_action_model,
+        include_signature=include_signature,
+    )
+
+
+def document_collection_method(
+    section,
+    resource_name,
+    action_name,
+    event_emitter,
+    collection_model,
+    service_model,
+    include_signature=True,
+):
+    """Documents a collection method
+
+    :param section: The section to write to
+
+    :param resource_name: The name of the resource
+
+    :param action_name: The name of collection action. Currently only
+        can be all, filter, limit, or page_size
+
+    :param event_emitter: The event emitter to use to emit events
+
+    :param collection_model: The model of the collection
+
+    :param service_model: The model of the service
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    operation_model = service_model.operation_model(
+        collection_model.request.operation
+    )
+
+    underlying_operation_members = []
+    if operation_model.input_shape:
+        underlying_operation_members = operation_model.input_shape.members
+
+    example_resource_name = xform_name(resource_name)
+    if service_model.service_name == resource_name:
+        example_resource_name = resource_name
+
+    custom_action_info_dict = {
+        'all': {
+            'method_description': (
+                f'Creates an iterable of all {collection_model.resource.type} '
+                f'resources in the collection.'
+            ),
+            'example_prefix': f'{xform_name(collection_model.resource.type)}_iterator = {example_resource_name}.{collection_model.name}.all',
+            'exclude_input': underlying_operation_members,
+        },
+        'filter': {
+            'method_description': (
+                f'Creates an iterable of all {collection_model.resource.type} '
+                f'resources in the collection filtered by kwargs passed to '
+                f'method. A {collection_model.resource.type} collection will '
+                f'include all resources by default if no filters are provided, '
+                f'and extreme caution should be taken when performing actions '
+                f'on all resources.'
+            ),
+            'example_prefix': f'{xform_name(collection_model.resource.type)}_iterator = {example_resource_name}.{collection_model.name}.filter',
+            'exclude_input': get_resource_ignore_params(
+                collection_model.request.params
+            ),
+        },
+        'limit': {
+            'method_description': (
+                f'Creates an iterable up to a specified amount of '
+                f'{collection_model.resource.type} resources in the collection.'
+            ),
+            'example_prefix': f'{xform_name(collection_model.resource.type)}_iterator = {example_resource_name}.{collection_model.name}.limit',
+            'include_input': [
+                DocumentedShape(
+                    name='count',
+                    type_name='integer',
+                    documentation=(
+                        'The limit to the number of resources '
+                        'in the iterable.'
+                    ),
+                )
+            ],
+            'exclude_input': underlying_operation_members,
+        },
+        'page_size': {
+            'method_description': (
+                f'Creates an iterable of all {collection_model.resource.type} '
+                f'resources in the collection, but limits the number of '
+                f'items returned by each service call by the specified amount.'
+            ),
+            'example_prefix': f'{xform_name(collection_model.resource.type)}_iterator = {example_resource_name}.{collection_model.name}.page_size',
+            'include_input': [
+                DocumentedShape(
+                    name='count',
+                    type_name='integer',
+                    documentation=(
+                        'The number of items returned by each ' 'service call'
+                    ),
+                )
+            ],
+            'exclude_input': underlying_operation_members,
+        },
+    }
+    if action_name in custom_action_info_dict:
+        action_info = custom_action_info_dict[action_name]
+        document_model_driven_resource_method(
+            section=section,
+            method_name=action_name,
+            operation_model=operation_model,
+            event_emitter=event_emitter,
+            resource_action_model=collection_model,
+            include_signature=include_signature,
+            **action_info,
+        )
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/docstring.py b/.venv/lib/python3.12/site-packages/boto3/docs/docstring.py
new file mode 100644
index 00000000..daf67873
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/docstring.py
@@ -0,0 +1,77 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.docstring import LazyLoadedDocstring
+
+from boto3.docs.action import document_action, document_load_reload_action
+from boto3.docs.attr import (
+    document_attribute,
+    document_identifier,
+    document_reference,
+)
+from boto3.docs.collection import (
+    document_batch_action,
+    document_collection_method,
+    document_collection_object,
+)
+from boto3.docs.subresource import document_sub_resource
+from boto3.docs.waiter import document_resource_waiter
+
+
+class ActionDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_action(*args, **kwargs)
+
+
+class LoadReloadDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_load_reload_action(*args, **kwargs)
+
+
+class SubResourceDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_sub_resource(*args, **kwargs)
+
+
+class AttributeDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_attribute(*args, **kwargs)
+
+
+class IdentifierDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_identifier(*args, **kwargs)
+
+
+class ReferenceDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_reference(*args, **kwargs)
+
+
+class CollectionDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_collection_object(*args, **kwargs)
+
+
+class CollectionMethodDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_collection_method(*args, **kwargs)
+
+
+class BatchActionDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_batch_action(*args, **kwargs)
+
+
+class ResourceWaiterDocstring(LazyLoadedDocstring):
+    def _write_docstring(self, *args, **kwargs):
+        document_resource_waiter(*args, **kwargs)
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/method.py b/.venv/lib/python3.12/site-packages/boto3/docs/method.py
new file mode 100644
index 00000000..a5b3b250
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/method.py
@@ -0,0 +1,77 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from botocore.docs.method import document_model_driven_method
+
+
+def document_model_driven_resource_method(
+    section,
+    method_name,
+    operation_model,
+    event_emitter,
+    method_description=None,
+    example_prefix=None,
+    include_input=None,
+    include_output=None,
+    exclude_input=None,
+    exclude_output=None,
+    document_output=True,
+    resource_action_model=None,
+    include_signature=True,
+):
+    document_model_driven_method(
+        section=section,
+        method_name=method_name,
+        operation_model=operation_model,
+        event_emitter=event_emitter,
+        method_description=method_description,
+        example_prefix=example_prefix,
+        include_input=include_input,
+        include_output=include_output,
+        exclude_input=exclude_input,
+        exclude_output=exclude_output,
+        document_output=document_output,
+        include_signature=include_signature,
+    )
+
+    # If this action returns a resource modify the return example to
+    # appropriately reflect that.
+    if resource_action_model.resource:
+        if 'return' in section.available_sections:
+            section.delete_section('return')
+        resource_type = resource_action_model.resource.type
+
+        new_return_section = section.add_new_section('return')
+        return_resource_type = (
+            f'{operation_model.service_model.service_name}.{resource_type}'
+        )
+
+        return_type = f':py:class:`{return_resource_type}`'
+        return_description = f'{resource_type} resource'
+
+        if _method_returns_resource_list(resource_action_model.resource):
+            return_type = f'list({return_type})'
+            return_description = f'A list of {resource_type} resources'
+
+        new_return_section.style.new_line()
+        new_return_section.write(f':rtype: {return_type}')
+        new_return_section.style.new_line()
+        new_return_section.write(f':returns: {return_description}')
+        new_return_section.style.new_line()
+
+
+def _method_returns_resource_list(resource):
+    for identifier in resource.identifiers:
+        if identifier.path and '[]' in identifier.path:
+            return True
+
+    return False
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/resource.py b/.venv/lib/python3.12/site-packages/boto3/docs/resource.py
new file mode 100644
index 00000000..2e3464e3
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/resource.py
@@ -0,0 +1,354 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.utils import get_official_service_name
+
+from boto3.docs.action import ActionDocumenter
+from boto3.docs.attr import (
+    document_attribute,
+    document_identifier,
+    document_reference,
+)
+from boto3.docs.base import BaseDocumenter
+from boto3.docs.collection import CollectionDocumenter
+from boto3.docs.subresource import SubResourceDocumenter
+from boto3.docs.utils import (
+    add_resource_type_overview,
+    get_identifier_args_for_signature,
+    get_identifier_description,
+    get_identifier_values_for_example,
+)
+from boto3.docs.waiter import WaiterResourceDocumenter
+
+
+class ResourceDocumenter(BaseDocumenter):
+    def __init__(self, resource, botocore_session, root_docs_path):
+        super().__init__(resource)
+        self._botocore_session = botocore_session
+        self._root_docs_path = root_docs_path
+        self._resource_sub_path = self._resource_name.lower()
+        if self._resource_name == self._service_name:
+            self._resource_sub_path = 'service-resource'
+
+    def document_resource(self, section):
+        self._add_title(section)
+        self._add_resource_note(section)
+        self._add_intro(section)
+        self._add_identifiers(section)
+        self._add_attributes(section)
+        self._add_references(section)
+        self._add_actions(section)
+        self._add_sub_resources(section)
+        self._add_collections(section)
+        self._add_waiters(section)
+
+    def _add_title(self, section):
+        title_section = section.add_new_section('title')
+        title_section.style.h2(self._resource_name)
+
+    def _add_intro(self, section):
+        identifier_names = []
+        if self._resource_model.identifiers:
+            for identifier in self._resource_model.identifiers:
+                identifier_names.append(identifier.name)
+
+        # Write out the class signature.
+        class_args = get_identifier_args_for_signature(identifier_names)
+        start_class = section.add_new_section('start_class')
+        start_class.style.start_sphinx_py_class(
+            class_name=f'{self.class_name}({class_args})'
+        )
+
+        # Add as short description about the resource
+        description_section = start_class.add_new_section('description')
+        self._add_description(description_section)
+
+        # Add an example of how to instantiate the resource
+        example_section = start_class.add_new_section('example')
+        self._add_example(example_section, identifier_names)
+
+        # Add the description for the parameters to instantiate the
+        # resource.
+        param_section = start_class.add_new_section('params')
+        self._add_params_description(param_section, identifier_names)
+
+        end_class = section.add_new_section('end_class')
+        end_class.style.end_sphinx_py_class()
+
+    def _add_description(self, section):
+        official_service_name = get_official_service_name(self._service_model)
+        section.write(
+            f'A resource representing an {official_service_name} {self._resource_name}'
+        )
+
+    def _add_example(self, section, identifier_names):
+        section.style.start_codeblock()
+        section.style.new_line()
+        section.write('import boto3')
+        section.style.new_line()
+        section.style.new_line()
+        section.write(
+            f'{self._service_name} = boto3.resource(\'{self._service_name}\')'
+        )
+        section.style.new_line()
+        example_values = get_identifier_values_for_example(identifier_names)
+        section.write(
+            f'{xform_name(self._resource_name)} = {self._service_name}.{self._resource_name}({example_values})'
+        )
+        section.style.end_codeblock()
+
+    def _add_params_description(self, section, identifier_names):
+        for identifier_name in identifier_names:
+            description = get_identifier_description(
+                self._resource_name, identifier_name
+            )
+            section.write(f':type {identifier_name}: string')
+            section.style.new_line()
+            section.write(f':param {identifier_name}: {description}')
+            section.style.new_line()
+
+    def _add_overview_of_member_type(self, section, resource_member_type):
+        section.style.new_line()
+        section.write(
+            f'These are the resource\'s available {resource_member_type}:'
+        )
+        section.style.new_line()
+        section.style.toctree()
+        for member in self.member_map[resource_member_type]:
+            section.style.tocitem(f'{member}')
+
+    def _add_identifiers(self, section):
+        identifiers = self._resource.meta.resource_model.identifiers
+        section = section.add_new_section('identifiers')
+        member_list = []
+        if identifiers:
+            self.member_map['identifiers'] = member_list
+            add_resource_type_overview(
+                section=section,
+                resource_type='Identifiers',
+                description=(
+                    'Identifiers are properties of a resource that are '
+                    'set upon instantiation of the resource.'
+                ),
+                intro_link='identifiers_attributes_intro',
+            )
+        for identifier in identifiers:
+            member_list.append(identifier.name)
+            # Create a new DocumentStructure for each identifier and add contents.
+            identifier_doc = DocumentStructure(identifier.name, target='html')
+            breadcrumb_section = identifier_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Identifier / {identifier.name}')
+            identifier_doc.add_title_section(identifier.name)
+            identifier_section = identifier_doc.add_new_section(
+                identifier.name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            document_identifier(
+                section=identifier_section,
+                resource_name=self._resource_name,
+                identifier_model=identifier,
+            )
+            # Write identifiers in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<identifier_name>.rst
+            identifiers_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            identifier_doc.write_to_file(identifiers_dir_path, identifier.name)
+
+        if identifiers:
+            self._add_overview_of_member_type(section, 'identifiers')
+
+    def _add_attributes(self, section):
+        service_model = self._resource.meta.client.meta.service_model
+        attributes = {}
+        if self._resource.meta.resource_model.shape:
+            shape = service_model.shape_for(
+                self._resource.meta.resource_model.shape
+            )
+            attributes = self._resource.meta.resource_model.get_attributes(
+                shape
+            )
+        section = section.add_new_section('attributes')
+        attribute_list = []
+        if attributes:
+            add_resource_type_overview(
+                section=section,
+                resource_type='Attributes',
+                description=(
+                    'Attributes provide access'
+                    ' to the properties of a resource. Attributes are lazy-'
+                    'loaded the first time one is accessed via the'
+                    ' :py:meth:`load` method.'
+                ),
+                intro_link='identifiers_attributes_intro',
+            )
+            self.member_map['attributes'] = attribute_list
+        for attr_name in sorted(attributes):
+            _, attr_shape = attributes[attr_name]
+            attribute_list.append(attr_name)
+            # Create a new DocumentStructure for each attribute and add contents.
+            attribute_doc = DocumentStructure(attr_name, target='html')
+            breadcrumb_section = attribute_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Attribute / {attr_name}')
+            attribute_doc.add_title_section(attr_name)
+            attribute_section = attribute_doc.add_new_section(
+                attr_name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            document_attribute(
+                section=attribute_section,
+                service_name=self._service_name,
+                resource_name=self._resource_name,
+                attr_name=attr_name,
+                event_emitter=self._resource.meta.client.meta.events,
+                attr_model=attr_shape,
+            )
+            # Write attributes in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<attribute_name>.rst
+            attributes_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            attribute_doc.write_to_file(attributes_dir_path, attr_name)
+        if attributes:
+            self._add_overview_of_member_type(section, 'attributes')
+
+    def _add_references(self, section):
+        section = section.add_new_section('references')
+        references = self._resource.meta.resource_model.references
+        reference_list = []
+        if references:
+            add_resource_type_overview(
+                section=section,
+                resource_type='References',
+                description=(
+                    'References are related resource instances that have '
+                    'a belongs-to relationship.'
+                ),
+                intro_link='references_intro',
+            )
+            self.member_map['references'] = reference_list
+        for reference in references:
+            reference_list.append(reference.name)
+            # Create a new DocumentStructure for each reference and add contents.
+            reference_doc = DocumentStructure(reference.name, target='html')
+            breadcrumb_section = reference_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Reference / {reference.name}')
+            reference_doc.add_title_section(reference.name)
+            reference_section = reference_doc.add_new_section(
+                reference.name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            document_reference(
+                section=reference_section,
+                reference_model=reference,
+            )
+            # Write references in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<reference_name>.rst
+            references_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            reference_doc.write_to_file(references_dir_path, reference.name)
+        if references:
+            self._add_overview_of_member_type(section, 'references')
+
+    def _add_actions(self, section):
+        section = section.add_new_section('actions')
+        actions = self._resource.meta.resource_model.actions
+        if actions:
+            documenter = ActionDocumenter(self._resource, self._root_docs_path)
+            documenter.member_map = self.member_map
+            documenter.document_actions(section)
+            self._add_overview_of_member_type(section, 'actions')
+
+    def _add_sub_resources(self, section):
+        section = section.add_new_section('sub-resources')
+        sub_resources = self._resource.meta.resource_model.subresources
+        if sub_resources:
+            documenter = SubResourceDocumenter(
+                self._resource, self._root_docs_path
+            )
+            documenter.member_map = self.member_map
+            documenter.document_sub_resources(section)
+            self._add_overview_of_member_type(section, 'sub-resources')
+
+    def _add_collections(self, section):
+        section = section.add_new_section('collections')
+        collections = self._resource.meta.resource_model.collections
+        if collections:
+            documenter = CollectionDocumenter(
+                self._resource, self._root_docs_path
+            )
+            documenter.member_map = self.member_map
+            documenter.document_collections(section)
+            self._add_overview_of_member_type(section, 'collections')
+
+    def _add_waiters(self, section):
+        section = section.add_new_section('waiters')
+        waiters = self._resource.meta.resource_model.waiters
+        if waiters:
+            service_waiter_model = self._botocore_session.get_waiter_model(
+                self._service_name
+            )
+            documenter = WaiterResourceDocumenter(
+                self._resource, service_waiter_model, self._root_docs_path
+            )
+            documenter.member_map = self.member_map
+            documenter.document_resource_waiters(section)
+            self._add_overview_of_member_type(section, 'waiters')
+
+    def _add_resource_note(self, section):
+        section = section.add_new_section('feature-freeze')
+        section.style.start_note()
+        section.write(
+            "Before using anything on this page, please refer to the resources "
+            ":doc:`user guide <../../../../guide/resources>` for the most recent "
+            "guidance on using resources."
+        )
+        section.style.end_note()
+
+
+class ServiceResourceDocumenter(ResourceDocumenter):
+    @property
+    def class_name(self):
+        return f'{self._service_docs_name}.ServiceResource'
+
+    def _add_title(self, section):
+        title_section = section.add_new_section('title')
+        title_section.style.h2('Service Resource')
+
+    def _add_description(self, section):
+        official_service_name = get_official_service_name(self._service_model)
+        section.write(f'A resource representing {official_service_name}')
+
+    def _add_example(self, section, identifier_names):
+        section.style.start_codeblock()
+        section.style.new_line()
+        section.write('import boto3')
+        section.style.new_line()
+        section.style.new_line()
+        section.write(
+            f'{self._service_name} = boto3.resource(\'{self._service_name}\')'
+        )
+        section.style.end_codeblock()
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/service.py b/.venv/lib/python3.12/site-packages/boto3/docs/service.py
new file mode 100644
index 00000000..39ed89b8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/service.py
@@ -0,0 +1,202 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.service import ServiceDocumenter as BaseServiceDocumenter
+from botocore.exceptions import DataNotFoundError
+
+import boto3
+from boto3.docs.client import Boto3ClientDocumenter
+from boto3.docs.resource import ResourceDocumenter, ServiceResourceDocumenter
+from boto3.utils import ServiceContext
+
+
+class ServiceDocumenter(BaseServiceDocumenter):
+    # The path used to find examples
+    EXAMPLE_PATH = os.path.join(os.path.dirname(boto3.__file__), 'examples')
+
+    def __init__(self, service_name, session, root_docs_path):
+        super().__init__(
+            service_name=service_name,
+            # I know that this is an internal attribute, but the botocore session
+            # is needed to load the paginator and waiter models.
+            session=session._session,
+            root_docs_path=root_docs_path,
+        )
+        self._boto3_session = session
+        self._client = self._boto3_session.client(service_name)
+        self._service_resource = None
+        if self._service_name in self._boto3_session.get_available_resources():
+            self._service_resource = self._boto3_session.resource(service_name)
+        self.sections = [
+            'title',
+            'client',
+            'paginators',
+            'waiters',
+            'resources',
+            'examples',
+            'context-params',
+        ]
+        self._root_docs_path = root_docs_path
+        self._USER_GUIDE_LINK = (
+            'https://boto3.amazonaws.com/'
+            'v1/documentation/api/latest/guide/resources.html'
+        )
+
+    def document_service(self):
+        """Documents an entire service.
+
+        :returns: The reStructured text of the documented service.
+        """
+        doc_structure = DocumentStructure(
+            self._service_name, section_names=self.sections, target='html'
+        )
+        self.title(doc_structure.get_section('title'))
+
+        self.client_api(doc_structure.get_section('client'))
+        self.paginator_api(doc_structure.get_section('paginators'))
+        self.waiter_api(doc_structure.get_section('waiters'))
+        if self._service_resource:
+            self.resource_section(doc_structure.get_section('resources'))
+        self._document_examples(doc_structure.get_section('examples'))
+        context_params_section = doc_structure.get_section('context-params')
+        self.client_context_params(context_params_section)
+        return doc_structure.flush_structure()
+
+    def client_api(self, section):
+        examples = None
+        try:
+            examples = self.get_examples(self._service_name)
+        except DataNotFoundError:
+            pass
+
+        Boto3ClientDocumenter(
+            self._client, self._root_docs_path, examples
+        ).document_client(section)
+
+    def resource_section(self, section):
+        section.style.h2('Resources')
+        section.style.new_line()
+        section.write(
+            'Resources are available in boto3 via the '
+            '``resource`` method. For more detailed instructions '
+            'and examples on the usage of resources, see the '
+            'resources '
+        )
+        section.style.external_link(
+            title='user guide',
+            link=self._USER_GUIDE_LINK,
+        )
+        section.write('.')
+        section.style.new_line()
+        section.style.new_line()
+        section.write('The available resources are:')
+        section.style.new_line()
+        section.style.toctree()
+        self._document_service_resource(section)
+        self._document_resources(section)
+
+    def _document_service_resource(self, section):
+        # Create a new DocumentStructure for each Service Resource and add contents.
+        service_resource_doc = DocumentStructure(
+            'service-resource', target='html'
+        )
+        breadcrumb_section = service_resource_doc.add_new_section('breadcrumb')
+        breadcrumb_section.style.ref(
+            self._client.__class__.__name__, f'../../{self._service_name}'
+        )
+        breadcrumb_section.write(' / Resource / ServiceResource')
+        ServiceResourceDocumenter(
+            self._service_resource, self._session, self._root_docs_path
+        ).document_resource(service_resource_doc)
+        # Write collections in individual/nested files.
+        # Path: <root>/reference/services/<service>/<resource_name>/<collection_name>.rst
+        resource_name = self._service_resource.meta.resource_model.name
+        if resource_name == self._service_name:
+            resource_name = 'service-resource'
+        service_resource_dir_path = os.path.join(
+            self._root_docs_path,
+            f'{self._service_name}',
+            f'{resource_name.lower()}',
+        )
+        service_resource_doc.write_to_file(service_resource_dir_path, 'index')
+        section.style.tocitem(f'{self._service_name}/{resource_name}/index')
+
+    def _document_resources(self, section):
+        temp_identifier_value = 'foo'
+        loader = self._session.get_component('data_loader')
+        json_resource_model = loader.load_service_model(
+            self._service_name, 'resources-1'
+        )
+        service_model = self._service_resource.meta.client.meta.service_model
+        for resource_name in json_resource_model['resources']:
+            resource_model = json_resource_model['resources'][resource_name]
+            resource_cls = (
+                self._boto3_session.resource_factory.load_from_definition(
+                    resource_name=resource_name,
+                    single_resource_json_definition=resource_model,
+                    service_context=ServiceContext(
+                        service_name=self._service_name,
+                        resource_json_definitions=json_resource_model[
+                            'resources'
+                        ],
+                        service_model=service_model,
+                        service_waiter_model=None,
+                    ),
+                )
+            )
+            identifiers = resource_cls.meta.resource_model.identifiers
+            args = []
+            for _ in identifiers:
+                args.append(temp_identifier_value)
+            resource = resource_cls(*args, client=self._client)
+            # Create a new DocumentStructure for each Resource and add contents.
+            resource_name = resource.meta.resource_model.name.lower()
+            resource_doc = DocumentStructure(resource_name, target='html')
+            breadcrumb_section = resource_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(
+                self._client.__class__.__name__, f'../../{self._service_name}'
+            )
+            breadcrumb_section.write(
+                f' / Resource / {resource.meta.resource_model.name}'
+            )
+            ResourceDocumenter(
+                resource, self._session, self._root_docs_path
+            ).document_resource(
+                resource_doc.add_new_section(resource.meta.resource_model.name)
+            )
+            # Write collections in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<index>.rst
+            service_resource_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{resource_name}',
+            )
+            resource_doc.write_to_file(service_resource_dir_path, 'index')
+            section.style.tocitem(
+                f'{self._service_name}/{resource_name}/index'
+            )
+
+    def _get_example_file(self):
+        return os.path.realpath(
+            os.path.join(self.EXAMPLE_PATH, self._service_name + '.rst')
+        )
+
+    def _document_examples(self, section):
+        examples_file = self._get_example_file()
+        if os.path.isfile(examples_file):
+            section.style.h2('Examples')
+            section.style.new_line()
+            with open(examples_file) as f:
+                section.write(f.read())
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/subresource.py b/.venv/lib/python3.12/site-packages/boto3/docs/subresource.py
new file mode 100644
index 00000000..a28203d4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/subresource.py
@@ -0,0 +1,145 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.utils import get_service_module_name
+
+from boto3.docs.base import NestedDocumenter
+from boto3.docs.utils import (
+    add_resource_type_overview,
+    get_identifier_args_for_signature,
+    get_identifier_description,
+    get_identifier_values_for_example,
+)
+
+
+class SubResourceDocumenter(NestedDocumenter):
+    def document_sub_resources(self, section):
+        add_resource_type_overview(
+            section=section,
+            resource_type='Sub-resources',
+            description=(
+                'Sub-resources are methods that create a new instance of a'
+                ' child resource. This resource\'s identifiers get passed'
+                ' along to the child.'
+            ),
+            intro_link='subresources_intro',
+        )
+        sub_resources = sorted(
+            self._resource.meta.resource_model.subresources,
+            key=lambda sub_resource: sub_resource.name,
+        )
+        sub_resources_list = []
+        self.member_map['sub-resources'] = sub_resources_list
+        for sub_resource in sub_resources:
+            sub_resources_list.append(sub_resource.name)
+            # Create a new DocumentStructure for each sub_resource and add contents.
+            sub_resource_doc = DocumentStructure(
+                sub_resource.name, target='html'
+            )
+            breadcrumb_section = sub_resource_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Sub-Resource / {sub_resource.name}')
+            sub_resource_doc.add_title_section(sub_resource.name)
+            sub_resource_section = sub_resource_doc.add_new_section(
+                sub_resource.name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            document_sub_resource(
+                section=sub_resource_section,
+                resource_name=self._resource_name,
+                sub_resource_model=sub_resource,
+                service_model=self._service_model,
+            )
+
+            # Write sub_resources in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<sub_resource_name>.rst
+            sub_resources_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            sub_resource_doc.write_to_file(
+                sub_resources_dir_path, sub_resource.name
+            )
+
+
+def document_sub_resource(
+    section,
+    resource_name,
+    sub_resource_model,
+    service_model,
+    include_signature=True,
+):
+    """Documents a resource action
+
+    :param section: The section to write to
+
+    :param resource_name: The name of the resource
+
+    :param sub_resource_model: The model of the subresource
+
+    :param service_model: The model of the service
+
+    :param include_signature: Whether or not to include the signature.
+        It is useful for generating docstrings.
+    """
+    identifiers_needed = []
+    for identifier in sub_resource_model.resource.identifiers:
+        if identifier.source == 'input':
+            identifiers_needed.append(xform_name(identifier.target))
+
+    if include_signature:
+        signature_args = get_identifier_args_for_signature(identifiers_needed)
+        full_sub_resource_name = (
+            f"{section.context.get('qualifier', '')}{sub_resource_model.name}"
+        )
+        section.style.start_sphinx_py_method(
+            full_sub_resource_name, signature_args
+        )
+
+    method_intro_section = section.add_new_section('method-intro')
+    description = f'Creates a {sub_resource_model.resource.type} resource.'
+    method_intro_section.include_doc_string(description)
+    example_section = section.add_new_section('example')
+    example_values = get_identifier_values_for_example(identifiers_needed)
+    example_resource_name = xform_name(resource_name)
+    if service_model.service_name == resource_name:
+        example_resource_name = resource_name
+    example = f'{xform_name(sub_resource_model.resource.type)} = {example_resource_name}.{sub_resource_model.name}({example_values})'
+    example_section.style.start_codeblock()
+    example_section.write(example)
+    example_section.style.end_codeblock()
+
+    param_section = section.add_new_section('params')
+    for identifier in identifiers_needed:
+        description = get_identifier_description(
+            sub_resource_model.name, identifier
+        )
+        param_section.write(f':type {identifier}: string')
+        param_section.style.new_line()
+        param_section.write(f':param {identifier}: {description}')
+        param_section.style.new_line()
+
+    return_section = section.add_new_section('return')
+    return_section.style.new_line()
+    return_section.write(
+        f':rtype: :py:class:`{get_service_module_name(service_model)}.{sub_resource_model.resource.type}`'
+    )
+    return_section.style.new_line()
+    return_section.write(
+        f':returns: A {sub_resource_model.resource.type} resource'
+    )
+    return_section.style.new_line()
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/utils.py b/.venv/lib/python3.12/site-packages/boto3/docs/utils.py
new file mode 100644
index 00000000..0830af50
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/utils.py
@@ -0,0 +1,146 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import inspect
+
+import jmespath
+
+
+def get_resource_ignore_params(params):
+    """Helper method to determine which parameters to ignore for actions
+
+    :returns: A list of the parameter names that does not need to be
+        included in a resource's method call for documentation purposes.
+    """
+    ignore_params = []
+    for param in params:
+        result = jmespath.compile(param.target)
+        current = result.parsed
+        # Use JMESPath to find the left most element in the target expression
+        # which will be the parameter to ignore in the action call.
+        while current['children']:
+            current = current['children'][0]
+        # Make sure the parameter we are about to ignore is a field.
+        # If it is not, we should ignore the result to avoid false positives.
+        if current['type'] == 'field':
+            ignore_params.append(current['value'])
+    return ignore_params
+
+
+def is_resource_action(action_handle):
+    return inspect.isfunction(action_handle)
+
+
+def get_resource_public_actions(resource_class):
+    resource_class_members = inspect.getmembers(resource_class)
+    resource_methods = {}
+    for name, member in resource_class_members:
+        if not name.startswith('_'):
+            if not name[0].isupper():
+                if not name.startswith('wait_until'):
+                    if is_resource_action(member):
+                        resource_methods[name] = member
+    return resource_methods
+
+
+def get_identifier_values_for_example(identifier_names):
+    return ','.join([f'\'{identifier}\'' for identifier in identifier_names])
+
+
+def get_identifier_args_for_signature(identifier_names):
+    return ','.join(identifier_names)
+
+
+def get_identifier_description(resource_name, identifier_name):
+    return (
+        f"The {resource_name}'s {identifier_name} identifier. "
+        f"This **must** be set."
+    )
+
+
+def add_resource_type_overview(
+    section, resource_type, description, intro_link=None
+):
+    section.style.new_line()
+    section.style.h3(resource_type)
+    section.style.new_line()
+    section.style.new_line()
+    section.write(description)
+    section.style.new_line()
+    if intro_link is not None:
+        section.write(
+            f'For more information about {resource_type.lower()} refer to the '
+            f':ref:`Resources Introduction Guide<{intro_link}>`.'
+        )
+        section.style.new_line()
+
+
+class DocumentModifiedShape:
+    def __init__(
+        self, shape_name, new_type, new_description, new_example_value
+    ):
+        self._shape_name = shape_name
+        self._new_type = new_type
+        self._new_description = new_description
+        self._new_example_value = new_example_value
+
+    def replace_documentation_for_matching_shape(
+        self, event_name, section, **kwargs
+    ):
+        if self._shape_name == section.context.get('shape'):
+            self._replace_documentation(event_name, section)
+        for section_name in section.available_sections:
+            sub_section = section.get_section(section_name)
+            if self._shape_name == sub_section.context.get('shape'):
+                self._replace_documentation(event_name, sub_section)
+            else:
+                self.replace_documentation_for_matching_shape(
+                    event_name, sub_section
+                )
+
+    def _replace_documentation(self, event_name, section):
+        if event_name.startswith(
+            'docs.request-example'
+        ) or event_name.startswith('docs.response-example'):
+            section.remove_all_sections()
+            section.clear_text()
+            section.write(self._new_example_value)
+
+        if event_name.startswith(
+            'docs.request-params'
+        ) or event_name.startswith('docs.response-params'):
+            allowed_sections = (
+                'param-name',
+                'param-documentation',
+                'end-structure',
+                'param-type',
+                'end-param',
+            )
+            for section_name in section.available_sections:
+                # Delete any extra members as a new shape is being
+                # used.
+                if section_name not in allowed_sections:
+                    section.delete_section(section_name)
+
+            # Update the documentation
+            description_section = section.get_section('param-documentation')
+            description_section.clear_text()
+            description_section.write(self._new_description)
+
+            # Update the param type
+            type_section = section.get_section('param-type')
+            if type_section.getvalue().decode('utf-8').startswith(':type'):
+                type_section.clear_text()
+                type_section.write(f':type {section.name}: {self._new_type}')
+            else:
+                type_section.clear_text()
+                type_section.style.italics(f'({self._new_type}) -- ')
diff --git a/.venv/lib/python3.12/site-packages/boto3/docs/waiter.py b/.venv/lib/python3.12/site-packages/boto3/docs/waiter.py
new file mode 100644
index 00000000..4713ce74
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/boto3/docs/waiter.py
@@ -0,0 +1,130 @@
+# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# https://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import os
+
+from botocore import xform_name
+from botocore.docs.bcdoc.restdoc import DocumentStructure
+from botocore.docs.method import document_model_driven_method
+from botocore.utils import get_service_module_name
+
+from boto3.docs.base import NestedDocumenter
+from boto3.docs.utils import (
+    add_resource_type_overview,
+    get_resource_ignore_params,
+)
+
+
+class WaiterResourceDocumenter(NestedDocumenter):
+    def __init__(self, resource, service_waiter_model, root_docs_path):
+        super().__init__(resource, root_docs_path)
+        self._service_waiter_model = service_waiter_model
+
+    def document_resource_waiters(self, section):
+        waiters = self._resource.meta.resource_model.waiters
+        add_resource_type_overview(
+            section=section,
+            resource_type='Waiters',
+            description=(
+                'Waiters provide an interface to wait for a resource'
+                ' to reach a specific state.'
+            ),
+            intro_link='waiters_intro',
+        )
+        waiter_list = []
+        self.member_map['waiters'] = waiter_list
+        for waiter in waiters:
+            waiter_list.append(waiter.name)
+            # Create a new DocumentStructure for each waiter and add contents.
+            waiter_doc = DocumentStructure(waiter.name, target='html')
+            breadcrumb_section = waiter_doc.add_new_section('breadcrumb')
+            breadcrumb_section.style.ref(self._resource_class_name, 'index')
+            breadcrumb_section.write(f' / Waiter / {waiter.name}')
+            waiter_doc.add_title_section(waiter.name)
+            waiter_section = waiter_doc.add_new_section(
+                waiter.name,
+                context={'qualifier': f'{self.class_name}.'},
+            )
+            document_resource_waiter(
+                section=waiter_section,
+                resource_name=self._resource_name,
+                event_emitter=self._resource.meta.client.meta.events,
+                service_model=self._service_model,
+                resource_waiter_model=waiter,
+                service_waiter_model=self._service_waiter_model,
+            )
+            # Write waiters in individual/nested files.
+            # Path: <root>/reference/services/<service>/<resource_name>/<waiter_name>.rst
+            waiters_dir_path = os.path.join(
+                self._root_docs_path,
+                f'{self._service_name}',
+                f'{self._resource_sub_path}',
+            )
+            waiter_doc.write_to_file(waiters_dir_path, waiter.name)
+
+
+def document_resource_waiter(
+    section,
+    resource_name,
+    event_emitter,
+    service_model,
+    resource_waiter_model,
+    service_waiter_model,
+    include_signature=True,
+):
+    waiter_model = service_waiter_model.get_waiter(
+        resource_waiter_model.waiter_name
+    )
+    operation_model = service_model.operation_model(waiter_model.operation)
+
+    ignore_params = get_resource_ignore_params(resource_waiter_model.params)
+    service_module_name = get_service_module_name(service_model)
+    description = (
+        'Waits until this {} is {}. This method calls '
+        ':py:meth:`{}.Waiter.{}.wait` which polls '
+        ':py:meth:`{}.Client.{}` every {} seconds until '
+        'a successful state is reached. An error is raised '
+        'after {} failed checks.'.format(
+            resource_name,
+            ' '.join(resource_waiter_model.name.split('_')[2:]),
+            service_module_name,
+            xform_name(resource_waiter_model.waiter_name),
+            service_module_name,
+            xform_name(waiter_model.operation),
+            waiter_model.delay,
+            waiter_model.max_attempts,
+        )
+    )
+    example_prefix = (
+        f'{xform_name(resource_name)}.{resource_waiter_model.name}'
+    )
+    full_waiter_name = (
+        f"{section.context.get('qualifier', '')}{resource_waiter_model.name}"
+    )
+    document_model_driven_method(
+        section=section,
+        method_name=full_waiter_name,
+        operation_model=operation_model,
+        event_emitter=event_emitter,
+        example_prefix=example_prefix,
+        method_description=description,
+        exclude_input=ignore_params,
+        include_signature=include_signature,
+    )
+    if 'return' in section.available_sections:
+        # Waiters do not return anything so we should remove
+        # any sections that may document the underlying return
+        # value of the client method.
+        return_section = section.get_section('return')
+        return_section.clear_text()
+        return_section.remove_all_sections()
+        return_section.write(':returns: None')