Parameters **must** be passed as keyword arguments. They will not work
as positional arguments.
.._references_intro:
References
----------
A reference is an attribute which may be ``None`` or a related resource
instance. The resource instance does not share identifiers with its
reference resource, that is, it is not a strict parent to child relationship.
In relational terms, these can be considered many-to-one or one-to-one.
Examples of references::
# EC2 Instance
instance.subnet
instance.vpc
In the above example, an EC2 instance may have exactly one associated
subnet, and may have exactly one associated VPC. The subnet does not
require the instance ID to exist, hence it is not a parent to child
relationship.
.._subresources_intro:
Sub-resources
-------------
A sub-resource is similar to a reference, but is a related class rather than
an instance. Sub-resources, when instantiated, share identifiers with their
parent. It is a strict parent-child relationship. In relational terms, these
can be considered one-to-many. Examples of sub-resources::
# SQS
queue = sqs.Queue(url='...')
message = queue.Message(receipt_handle='...')
print(queue.url == message.queue_url)
print(message.receipt_handle)
# S3
obj = bucket.Object(key='new_file.txt')
print(obj.bucket_name)
print(obj.key)
Because an SQS message cannot exist without a queue, and an S3 object cannot
exist without a bucket, these are parent to child relationships.
.._waiters_intro:
Waiters
-------
A waiter is similiar to an action. A waiter will poll the status of a
resource and suspend execution until the resource reaches the state that is
being polling for or a failure occurs while polling.
Waiters automatically set the resource
identifiers as parameters, but allow you to pass additional parameters via
keyword arguments. Examples of waiters include::
# S3: Wait for a bucket to exist.
bucket.wait_until_exists()
# EC2: Wait for an instance to reach the running state.
instance.wait_until_running()
Multithreading
--------------
It is recommended to create a resource instance for each thread in a multithreaded application rather than sharing a single instance among the threads. For example::
import boto3
import boto3.session
import threading
class MyTask(threading.Thread):
def run(self):
session = boto3.session.Session()
s3 = session.resource('s3')
# ... do some work with S3 ...
In the example above, each thread would have its own Boto 3 session and its own instance of the S3 resource. This is a good idea because resources contain shared data when loaded and calling actions, accessing properties, or manually loading or reloading the resource can modify this data.