# coding=utf-8
# *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. ***
# *** Do not edit by hand unless you're certain you know what you are doing! ***

import warnings
import pulumi
import pulumi.runtime
from typing import Any, Mapping, Optional, Sequence, Union, overload
from .. import _utilities

__all__ = ['BucketObjectArgs', 'BucketObject']

@pulumi.input_type
class BucketObjectArgs:
    def __init__(__self__, *,
                 bucket: pulumi.Input[str],
                 acl: Optional[pulumi.Input[str]] = None,
                 bucket_key_enabled: Optional[pulumi.Input[bool]] = None,
                 cache_control: Optional[pulumi.Input[str]] = None,
                 content: Optional[pulumi.Input[str]] = None,
                 content_base64: Optional[pulumi.Input[str]] = None,
                 content_disposition: Optional[pulumi.Input[str]] = None,
                 content_encoding: Optional[pulumi.Input[str]] = None,
                 content_language: Optional[pulumi.Input[str]] = None,
                 content_type: Optional[pulumi.Input[str]] = None,
                 etag: Optional[pulumi.Input[str]] = None,
                 force_destroy: Optional[pulumi.Input[bool]] = None,
                 key: Optional[pulumi.Input[str]] = None,
                 kms_key_id: Optional[pulumi.Input[str]] = None,
                 metadata: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 object_lock_legal_hold_status: Optional[pulumi.Input[str]] = None,
                 object_lock_mode: Optional[pulumi.Input[str]] = None,
                 object_lock_retain_until_date: Optional[pulumi.Input[str]] = None,
                 server_side_encryption: Optional[pulumi.Input[str]] = None,
                 source: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]] = None,
                 source_hash: Optional[pulumi.Input[str]] = None,
                 storage_class: Optional[pulumi.Input[str]] = None,
                 tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 website_redirect: Optional[pulumi.Input[str]] = None):
        """
        The set of arguments for constructing a BucketObject resource.
        :param pulumi.Input[str] bucket: Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        :param pulumi.Input[str] acl: [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        :param pulumi.Input[bool] bucket_key_enabled: Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        :param pulumi.Input[str] cache_control: Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        :param pulumi.Input[str] content: Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        :param pulumi.Input[str] content_base64: Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        :param pulumi.Input[str] content_disposition: Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        :param pulumi.Input[str] content_encoding: Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        :param pulumi.Input[str] content_language: Language the content is in e.g., en-US or en-GB.
        :param pulumi.Input[str] content_type: Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        :param pulumi.Input[str] etag: Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        :param pulumi.Input[bool] force_destroy: Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        :param pulumi.Input[str] key: Name of the object once it is in the bucket.
        :param pulumi.Input[str] kms_key_id: ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] metadata: Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        :param pulumi.Input[str] object_lock_legal_hold_status: [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        :param pulumi.Input[str] object_lock_mode: Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        :param pulumi.Input[str] object_lock_retain_until_date: Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        :param pulumi.Input[str] server_side_encryption: Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        :param pulumi.Input[Union[pulumi.Asset, pulumi.Archive]] source: Path to a file that will be read and uploaded as raw bytes for the object content.
        :param pulumi.Input[str] source_hash: Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        :param pulumi.Input[str] storage_class: [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags: Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        :param pulumi.Input[str] website_redirect: Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        if bucket is not None:
            warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
            pulumi.log.warn("""bucket is deprecated: Use the aws_s3_object resource instead""")
        pulumi.set(__self__, "bucket", bucket)
        if acl is not None:
            pulumi.set(__self__, "acl", acl)
        if bucket_key_enabled is not None:
            pulumi.set(__self__, "bucket_key_enabled", bucket_key_enabled)
        if cache_control is not None:
            pulumi.set(__self__, "cache_control", cache_control)
        if content is not None:
            pulumi.set(__self__, "content", content)
        if content_base64 is not None:
            pulumi.set(__self__, "content_base64", content_base64)
        if content_disposition is not None:
            pulumi.set(__self__, "content_disposition", content_disposition)
        if content_encoding is not None:
            pulumi.set(__self__, "content_encoding", content_encoding)
        if content_language is not None:
            pulumi.set(__self__, "content_language", content_language)
        if content_type is not None:
            pulumi.set(__self__, "content_type", content_type)
        if etag is not None:
            pulumi.set(__self__, "etag", etag)
        if force_destroy is not None:
            pulumi.set(__self__, "force_destroy", force_destroy)
        if key is not None:
            warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
            pulumi.log.warn("""key is deprecated: Use the aws_s3_object resource instead""")
        if key is not None:
            pulumi.set(__self__, "key", key)
        if kms_key_id is not None:
            pulumi.set(__self__, "kms_key_id", kms_key_id)
        if metadata is not None:
            pulumi.set(__self__, "metadata", metadata)
        if object_lock_legal_hold_status is not None:
            pulumi.set(__self__, "object_lock_legal_hold_status", object_lock_legal_hold_status)
        if object_lock_mode is not None:
            pulumi.set(__self__, "object_lock_mode", object_lock_mode)
        if object_lock_retain_until_date is not None:
            pulumi.set(__self__, "object_lock_retain_until_date", object_lock_retain_until_date)
        if server_side_encryption is not None:
            pulumi.set(__self__, "server_side_encryption", server_side_encryption)
        if source is not None:
            pulumi.set(__self__, "source", source)
        if source_hash is not None:
            pulumi.set(__self__, "source_hash", source_hash)
        if storage_class is not None:
            pulumi.set(__self__, "storage_class", storage_class)
        if tags is not None:
            pulumi.set(__self__, "tags", tags)
        if website_redirect is not None:
            pulumi.set(__self__, "website_redirect", website_redirect)

    @property
    @pulumi.getter
    def bucket(self) -> pulumi.Input[str]:
        """
        Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        """
        return pulumi.get(self, "bucket")

    @bucket.setter
    def bucket(self, value: pulumi.Input[str]):
        pulumi.set(self, "bucket", value)

    @property
    @pulumi.getter
    def acl(self) -> Optional[pulumi.Input[str]]:
        """
        [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        """
        return pulumi.get(self, "acl")

    @acl.setter
    def acl(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "acl", value)

    @property
    @pulumi.getter(name="bucketKeyEnabled")
    def bucket_key_enabled(self) -> Optional[pulumi.Input[bool]]:
        """
        Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        """
        return pulumi.get(self, "bucket_key_enabled")

    @bucket_key_enabled.setter
    def bucket_key_enabled(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "bucket_key_enabled", value)

    @property
    @pulumi.getter(name="cacheControl")
    def cache_control(self) -> Optional[pulumi.Input[str]]:
        """
        Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        """
        return pulumi.get(self, "cache_control")

    @cache_control.setter
    def cache_control(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "cache_control", value)

    @property
    @pulumi.getter
    def content(self) -> Optional[pulumi.Input[str]]:
        """
        Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        """
        return pulumi.get(self, "content")

    @content.setter
    def content(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content", value)

    @property
    @pulumi.getter(name="contentBase64")
    def content_base64(self) -> Optional[pulumi.Input[str]]:
        """
        Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        """
        return pulumi.get(self, "content_base64")

    @content_base64.setter
    def content_base64(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_base64", value)

    @property
    @pulumi.getter(name="contentDisposition")
    def content_disposition(self) -> Optional[pulumi.Input[str]]:
        """
        Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        """
        return pulumi.get(self, "content_disposition")

    @content_disposition.setter
    def content_disposition(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_disposition", value)

    @property
    @pulumi.getter(name="contentEncoding")
    def content_encoding(self) -> Optional[pulumi.Input[str]]:
        """
        Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        """
        return pulumi.get(self, "content_encoding")

    @content_encoding.setter
    def content_encoding(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_encoding", value)

    @property
    @pulumi.getter(name="contentLanguage")
    def content_language(self) -> Optional[pulumi.Input[str]]:
        """
        Language the content is in e.g., en-US or en-GB.
        """
        return pulumi.get(self, "content_language")

    @content_language.setter
    def content_language(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_language", value)

    @property
    @pulumi.getter(name="contentType")
    def content_type(self) -> Optional[pulumi.Input[str]]:
        """
        Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        """
        return pulumi.get(self, "content_type")

    @content_type.setter
    def content_type(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_type", value)

    @property
    @pulumi.getter
    def etag(self) -> Optional[pulumi.Input[str]]:
        """
        Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        """
        return pulumi.get(self, "etag")

    @etag.setter
    def etag(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "etag", value)

    @property
    @pulumi.getter(name="forceDestroy")
    def force_destroy(self) -> Optional[pulumi.Input[bool]]:
        """
        Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        """
        return pulumi.get(self, "force_destroy")

    @force_destroy.setter
    def force_destroy(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "force_destroy", value)

    @property
    @pulumi.getter
    def key(self) -> Optional[pulumi.Input[str]]:
        """
        Name of the object once it is in the bucket.
        """
        return pulumi.get(self, "key")

    @key.setter
    def key(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "key", value)

    @property
    @pulumi.getter(name="kmsKeyId")
    def kms_key_id(self) -> Optional[pulumi.Input[str]]:
        """
        ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        """
        return pulumi.get(self, "kms_key_id")

    @kms_key_id.setter
    def kms_key_id(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "kms_key_id", value)

    @property
    @pulumi.getter
    def metadata(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]:
        """
        Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        """
        return pulumi.get(self, "metadata")

    @metadata.setter
    def metadata(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]):
        pulumi.set(self, "metadata", value)

    @property
    @pulumi.getter(name="objectLockLegalHoldStatus")
    def object_lock_legal_hold_status(self) -> Optional[pulumi.Input[str]]:
        """
        [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        """
        return pulumi.get(self, "object_lock_legal_hold_status")

    @object_lock_legal_hold_status.setter
    def object_lock_legal_hold_status(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_legal_hold_status", value)

    @property
    @pulumi.getter(name="objectLockMode")
    def object_lock_mode(self) -> Optional[pulumi.Input[str]]:
        """
        Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        """
        return pulumi.get(self, "object_lock_mode")

    @object_lock_mode.setter
    def object_lock_mode(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_mode", value)

    @property
    @pulumi.getter(name="objectLockRetainUntilDate")
    def object_lock_retain_until_date(self) -> Optional[pulumi.Input[str]]:
        """
        Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        """
        return pulumi.get(self, "object_lock_retain_until_date")

    @object_lock_retain_until_date.setter
    def object_lock_retain_until_date(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_retain_until_date", value)

    @property
    @pulumi.getter(name="serverSideEncryption")
    def server_side_encryption(self) -> Optional[pulumi.Input[str]]:
        """
        Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        """
        return pulumi.get(self, "server_side_encryption")

    @server_side_encryption.setter
    def server_side_encryption(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "server_side_encryption", value)

    @property
    @pulumi.getter
    def source(self) -> Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]]:
        """
        Path to a file that will be read and uploaded as raw bytes for the object content.
        """
        return pulumi.get(self, "source")

    @source.setter
    def source(self, value: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]]):
        pulumi.set(self, "source", value)

    @property
    @pulumi.getter(name="sourceHash")
    def source_hash(self) -> Optional[pulumi.Input[str]]:
        """
        Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        """
        return pulumi.get(self, "source_hash")

    @source_hash.setter
    def source_hash(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "source_hash", value)

    @property
    @pulumi.getter(name="storageClass")
    def storage_class(self) -> Optional[pulumi.Input[str]]:
        """
        [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        """
        return pulumi.get(self, "storage_class")

    @storage_class.setter
    def storage_class(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "storage_class", value)

    @property
    @pulumi.getter
    def tags(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]:
        """
        Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        """
        return pulumi.get(self, "tags")

    @tags.setter
    def tags(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]):
        pulumi.set(self, "tags", value)

    @property
    @pulumi.getter(name="websiteRedirect")
    def website_redirect(self) -> Optional[pulumi.Input[str]]:
        """
        Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        return pulumi.get(self, "website_redirect")

    @website_redirect.setter
    def website_redirect(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "website_redirect", value)

@pulumi.input_type
class _BucketObjectState:
    def __init__(__self__, *,
                 acl: Optional[pulumi.Input[str]] = None,
                 bucket: Optional[pulumi.Input[str]] = None,
                 bucket_key_enabled: Optional[pulumi.Input[bool]] = None,
                 cache_control: Optional[pulumi.Input[str]] = None,
                 content: Optional[pulumi.Input[str]] = None,
                 content_base64: Optional[pulumi.Input[str]] = None,
                 content_disposition: Optional[pulumi.Input[str]] = None,
                 content_encoding: Optional[pulumi.Input[str]] = None,
                 content_language: Optional[pulumi.Input[str]] = None,
                 content_type: Optional[pulumi.Input[str]] = None,
                 etag: Optional[pulumi.Input[str]] = None,
                 force_destroy: Optional[pulumi.Input[bool]] = None,
                 key: Optional[pulumi.Input[str]] = None,
                 kms_key_id: Optional[pulumi.Input[str]] = None,
                 metadata: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 object_lock_legal_hold_status: Optional[pulumi.Input[str]] = None,
                 object_lock_mode: Optional[pulumi.Input[str]] = None,
                 object_lock_retain_until_date: Optional[pulumi.Input[str]] = None,
                 server_side_encryption: Optional[pulumi.Input[str]] = None,
                 source: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]] = None,
                 source_hash: Optional[pulumi.Input[str]] = None,
                 storage_class: Optional[pulumi.Input[str]] = None,
                 tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 tags_all: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 version_id: Optional[pulumi.Input[str]] = None,
                 website_redirect: Optional[pulumi.Input[str]] = None):
        """
        Input properties used for looking up and filtering BucketObject resources.
        :param pulumi.Input[str] acl: [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        :param pulumi.Input[str] bucket: Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        :param pulumi.Input[bool] bucket_key_enabled: Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        :param pulumi.Input[str] cache_control: Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        :param pulumi.Input[str] content: Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        :param pulumi.Input[str] content_base64: Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        :param pulumi.Input[str] content_disposition: Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        :param pulumi.Input[str] content_encoding: Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        :param pulumi.Input[str] content_language: Language the content is in e.g., en-US or en-GB.
        :param pulumi.Input[str] content_type: Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        :param pulumi.Input[str] etag: Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        :param pulumi.Input[bool] force_destroy: Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        :param pulumi.Input[str] key: Name of the object once it is in the bucket.
        :param pulumi.Input[str] kms_key_id: ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] metadata: Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        :param pulumi.Input[str] object_lock_legal_hold_status: [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        :param pulumi.Input[str] object_lock_mode: Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        :param pulumi.Input[str] object_lock_retain_until_date: Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        :param pulumi.Input[str] server_side_encryption: Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        :param pulumi.Input[Union[pulumi.Asset, pulumi.Archive]] source: Path to a file that will be read and uploaded as raw bytes for the object content.
        :param pulumi.Input[str] source_hash: Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        :param pulumi.Input[str] storage_class: [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags: Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags_all: Map of tags assigned to the resource, including those inherited from the provider `default_tags` configuration block.
        :param pulumi.Input[str] version_id: Unique version ID value for the object, if bucket versioning is enabled.
        :param pulumi.Input[str] website_redirect: Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        if acl is not None:
            pulumi.set(__self__, "acl", acl)
        if bucket is not None:
            warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
            pulumi.log.warn("""bucket is deprecated: Use the aws_s3_object resource instead""")
        if bucket is not None:
            pulumi.set(__self__, "bucket", bucket)
        if bucket_key_enabled is not None:
            pulumi.set(__self__, "bucket_key_enabled", bucket_key_enabled)
        if cache_control is not None:
            pulumi.set(__self__, "cache_control", cache_control)
        if content is not None:
            pulumi.set(__self__, "content", content)
        if content_base64 is not None:
            pulumi.set(__self__, "content_base64", content_base64)
        if content_disposition is not None:
            pulumi.set(__self__, "content_disposition", content_disposition)
        if content_encoding is not None:
            pulumi.set(__self__, "content_encoding", content_encoding)
        if content_language is not None:
            pulumi.set(__self__, "content_language", content_language)
        if content_type is not None:
            pulumi.set(__self__, "content_type", content_type)
        if etag is not None:
            pulumi.set(__self__, "etag", etag)
        if force_destroy is not None:
            pulumi.set(__self__, "force_destroy", force_destroy)
        if key is not None:
            warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
            pulumi.log.warn("""key is deprecated: Use the aws_s3_object resource instead""")
        if key is not None:
            pulumi.set(__self__, "key", key)
        if kms_key_id is not None:
            pulumi.set(__self__, "kms_key_id", kms_key_id)
        if metadata is not None:
            pulumi.set(__self__, "metadata", metadata)
        if object_lock_legal_hold_status is not None:
            pulumi.set(__self__, "object_lock_legal_hold_status", object_lock_legal_hold_status)
        if object_lock_mode is not None:
            pulumi.set(__self__, "object_lock_mode", object_lock_mode)
        if object_lock_retain_until_date is not None:
            pulumi.set(__self__, "object_lock_retain_until_date", object_lock_retain_until_date)
        if server_side_encryption is not None:
            pulumi.set(__self__, "server_side_encryption", server_side_encryption)
        if source is not None:
            pulumi.set(__self__, "source", source)
        if source_hash is not None:
            pulumi.set(__self__, "source_hash", source_hash)
        if storage_class is not None:
            pulumi.set(__self__, "storage_class", storage_class)
        if tags is not None:
            pulumi.set(__self__, "tags", tags)
        if tags_all is not None:
            pulumi.set(__self__, "tags_all", tags_all)
        if version_id is not None:
            pulumi.set(__self__, "version_id", version_id)
        if website_redirect is not None:
            pulumi.set(__self__, "website_redirect", website_redirect)

    @property
    @pulumi.getter
    def acl(self) -> Optional[pulumi.Input[str]]:
        """
        [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        """
        return pulumi.get(self, "acl")

    @acl.setter
    def acl(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "acl", value)

    @property
    @pulumi.getter
    def bucket(self) -> Optional[pulumi.Input[str]]:
        """
        Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        """
        return pulumi.get(self, "bucket")

    @bucket.setter
    def bucket(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "bucket", value)

    @property
    @pulumi.getter(name="bucketKeyEnabled")
    def bucket_key_enabled(self) -> Optional[pulumi.Input[bool]]:
        """
        Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        """
        return pulumi.get(self, "bucket_key_enabled")

    @bucket_key_enabled.setter
    def bucket_key_enabled(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "bucket_key_enabled", value)

    @property
    @pulumi.getter(name="cacheControl")
    def cache_control(self) -> Optional[pulumi.Input[str]]:
        """
        Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        """
        return pulumi.get(self, "cache_control")

    @cache_control.setter
    def cache_control(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "cache_control", value)

    @property
    @pulumi.getter
    def content(self) -> Optional[pulumi.Input[str]]:
        """
        Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        """
        return pulumi.get(self, "content")

    @content.setter
    def content(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content", value)

    @property
    @pulumi.getter(name="contentBase64")
    def content_base64(self) -> Optional[pulumi.Input[str]]:
        """
        Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        """
        return pulumi.get(self, "content_base64")

    @content_base64.setter
    def content_base64(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_base64", value)

    @property
    @pulumi.getter(name="contentDisposition")
    def content_disposition(self) -> Optional[pulumi.Input[str]]:
        """
        Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        """
        return pulumi.get(self, "content_disposition")

    @content_disposition.setter
    def content_disposition(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_disposition", value)

    @property
    @pulumi.getter(name="contentEncoding")
    def content_encoding(self) -> Optional[pulumi.Input[str]]:
        """
        Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        """
        return pulumi.get(self, "content_encoding")

    @content_encoding.setter
    def content_encoding(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_encoding", value)

    @property
    @pulumi.getter(name="contentLanguage")
    def content_language(self) -> Optional[pulumi.Input[str]]:
        """
        Language the content is in e.g., en-US or en-GB.
        """
        return pulumi.get(self, "content_language")

    @content_language.setter
    def content_language(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_language", value)

    @property
    @pulumi.getter(name="contentType")
    def content_type(self) -> Optional[pulumi.Input[str]]:
        """
        Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        """
        return pulumi.get(self, "content_type")

    @content_type.setter
    def content_type(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "content_type", value)

    @property
    @pulumi.getter
    def etag(self) -> Optional[pulumi.Input[str]]:
        """
        Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        """
        return pulumi.get(self, "etag")

    @etag.setter
    def etag(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "etag", value)

    @property
    @pulumi.getter(name="forceDestroy")
    def force_destroy(self) -> Optional[pulumi.Input[bool]]:
        """
        Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        """
        return pulumi.get(self, "force_destroy")

    @force_destroy.setter
    def force_destroy(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "force_destroy", value)

    @property
    @pulumi.getter
    def key(self) -> Optional[pulumi.Input[str]]:
        """
        Name of the object once it is in the bucket.
        """
        return pulumi.get(self, "key")

    @key.setter
    def key(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "key", value)

    @property
    @pulumi.getter(name="kmsKeyId")
    def kms_key_id(self) -> Optional[pulumi.Input[str]]:
        """
        ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        """
        return pulumi.get(self, "kms_key_id")

    @kms_key_id.setter
    def kms_key_id(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "kms_key_id", value)

    @property
    @pulumi.getter
    def metadata(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]:
        """
        Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        """
        return pulumi.get(self, "metadata")

    @metadata.setter
    def metadata(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]):
        pulumi.set(self, "metadata", value)

    @property
    @pulumi.getter(name="objectLockLegalHoldStatus")
    def object_lock_legal_hold_status(self) -> Optional[pulumi.Input[str]]:
        """
        [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        """
        return pulumi.get(self, "object_lock_legal_hold_status")

    @object_lock_legal_hold_status.setter
    def object_lock_legal_hold_status(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_legal_hold_status", value)

    @property
    @pulumi.getter(name="objectLockMode")
    def object_lock_mode(self) -> Optional[pulumi.Input[str]]:
        """
        Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        """
        return pulumi.get(self, "object_lock_mode")

    @object_lock_mode.setter
    def object_lock_mode(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_mode", value)

    @property
    @pulumi.getter(name="objectLockRetainUntilDate")
    def object_lock_retain_until_date(self) -> Optional[pulumi.Input[str]]:
        """
        Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        """
        return pulumi.get(self, "object_lock_retain_until_date")

    @object_lock_retain_until_date.setter
    def object_lock_retain_until_date(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "object_lock_retain_until_date", value)

    @property
    @pulumi.getter(name="serverSideEncryption")
    def server_side_encryption(self) -> Optional[pulumi.Input[str]]:
        """
        Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        """
        return pulumi.get(self, "server_side_encryption")

    @server_side_encryption.setter
    def server_side_encryption(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "server_side_encryption", value)

    @property
    @pulumi.getter
    def source(self) -> Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]]:
        """
        Path to a file that will be read and uploaded as raw bytes for the object content.
        """
        return pulumi.get(self, "source")

    @source.setter
    def source(self, value: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]]):
        pulumi.set(self, "source", value)

    @property
    @pulumi.getter(name="sourceHash")
    def source_hash(self) -> Optional[pulumi.Input[str]]:
        """
        Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        """
        return pulumi.get(self, "source_hash")

    @source_hash.setter
    def source_hash(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "source_hash", value)

    @property
    @pulumi.getter(name="storageClass")
    def storage_class(self) -> Optional[pulumi.Input[str]]:
        """
        [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        """
        return pulumi.get(self, "storage_class")

    @storage_class.setter
    def storage_class(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "storage_class", value)

    @property
    @pulumi.getter
    def tags(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]:
        """
        Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        """
        return pulumi.get(self, "tags")

    @tags.setter
    def tags(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]):
        pulumi.set(self, "tags", value)

    @property
    @pulumi.getter(name="tagsAll")
    def tags_all(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]:
        """
        Map of tags assigned to the resource, including those inherited from the provider `default_tags` configuration block.
        """
        return pulumi.get(self, "tags_all")

    @tags_all.setter
    def tags_all(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]):
        pulumi.set(self, "tags_all", value)

    @property
    @pulumi.getter(name="versionId")
    def version_id(self) -> Optional[pulumi.Input[str]]:
        """
        Unique version ID value for the object, if bucket versioning is enabled.
        """
        return pulumi.get(self, "version_id")

    @version_id.setter
    def version_id(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "version_id", value)

    @property
    @pulumi.getter(name="websiteRedirect")
    def website_redirect(self) -> Optional[pulumi.Input[str]]:
        """
        Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        return pulumi.get(self, "website_redirect")

    @website_redirect.setter
    def website_redirect(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "website_redirect", value)

class BucketObject(pulumi.CustomResource):
    @overload
    def __init__(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 acl: Optional[pulumi.Input[str]] = None,
                 bucket: Optional[pulumi.Input[str]] = None,
                 bucket_key_enabled: Optional[pulumi.Input[bool]] = None,
                 cache_control: Optional[pulumi.Input[str]] = None,
                 content: Optional[pulumi.Input[str]] = None,
                 content_base64: Optional[pulumi.Input[str]] = None,
                 content_disposition: Optional[pulumi.Input[str]] = None,
                 content_encoding: Optional[pulumi.Input[str]] = None,
                 content_language: Optional[pulumi.Input[str]] = None,
                 content_type: Optional[pulumi.Input[str]] = None,
                 etag: Optional[pulumi.Input[str]] = None,
                 force_destroy: Optional[pulumi.Input[bool]] = None,
                 key: Optional[pulumi.Input[str]] = None,
                 kms_key_id: Optional[pulumi.Input[str]] = None,
                 metadata: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 object_lock_legal_hold_status: Optional[pulumi.Input[str]] = None,
                 object_lock_mode: Optional[pulumi.Input[str]] = None,
                 object_lock_retain_until_date: Optional[pulumi.Input[str]] = None,
                 server_side_encryption: Optional[pulumi.Input[str]] = None,
                 source: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]] = None,
                 source_hash: Optional[pulumi.Input[str]] = None,
                 storage_class: Optional[pulumi.Input[str]] = None,
                 tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 website_redirect: Optional[pulumi.Input[str]] = None,
                 __props__=None):
        """
        ## Example Usage
        ### Encrypting with KMS Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplekms = aws.kms.Key("examplekms",
            description="KMS key 1",
            deletion_window_in_days=7)
        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            kms_key_id=examplekms.arn)
        ```
        ### Server Side Encryption with S3 Default Master Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            server_side_encryption="aws:kms")
        ```
        ### Server Side Encryption with AWS-Managed Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            server_side_encryption="AES256")
        ```
        ### S3 Object Lock

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket", object_lock_configuration=aws.s3.BucketV2ObjectLockConfigurationArgs(
            object_lock_enabled="Enabled",
        ))
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_versioning_v2 = aws.s3.BucketVersioningV2("exampleBucketVersioningV2",
            bucket=examplebucket.id,
            versioning_configuration=aws.s3.BucketVersioningV2VersioningConfigurationArgs(
                status="Enabled",
            ))
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("important.txt"),
            object_lock_legal_hold_status="ON",
            object_lock_mode="GOVERNANCE",
            object_lock_retain_until_date="2021-12-31T23:59:60Z",
            force_destroy=True,
            opts=pulumi.ResourceOptions(depends_on=[example_bucket_versioning_v2]))
        ```

        ## Import

        Objects can be imported using the `id`. The `id` is the bucket name and the key together e.g.,

        ```sh
         $ pulumi import aws:s3/bucketObject:BucketObject object some-bucket-name/some/key.txt
        ```

         Additionally, s3 url syntax can be used, e.g.,

        ```sh
         $ pulumi import aws:s3/bucketObject:BucketObject object s3://some-bucket-name/some/key.txt
        ```

        :param str resource_name: The name of the resource.
        :param pulumi.ResourceOptions opts: Options for the resource.
        :param pulumi.Input[str] acl: [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        :param pulumi.Input[str] bucket: Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        :param pulumi.Input[bool] bucket_key_enabled: Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        :param pulumi.Input[str] cache_control: Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        :param pulumi.Input[str] content: Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        :param pulumi.Input[str] content_base64: Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        :param pulumi.Input[str] content_disposition: Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        :param pulumi.Input[str] content_encoding: Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        :param pulumi.Input[str] content_language: Language the content is in e.g., en-US or en-GB.
        :param pulumi.Input[str] content_type: Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        :param pulumi.Input[str] etag: Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        :param pulumi.Input[bool] force_destroy: Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        :param pulumi.Input[str] key: Name of the object once it is in the bucket.
        :param pulumi.Input[str] kms_key_id: ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] metadata: Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        :param pulumi.Input[str] object_lock_legal_hold_status: [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        :param pulumi.Input[str] object_lock_mode: Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        :param pulumi.Input[str] object_lock_retain_until_date: Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        :param pulumi.Input[str] server_side_encryption: Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        :param pulumi.Input[Union[pulumi.Asset, pulumi.Archive]] source: Path to a file that will be read and uploaded as raw bytes for the object content.
        :param pulumi.Input[str] source_hash: Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        :param pulumi.Input[str] storage_class: [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags: Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        :param pulumi.Input[str] website_redirect: Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        ...
    @overload
    def __init__(__self__,
                 resource_name: str,
                 args: BucketObjectArgs,
                 opts: Optional[pulumi.ResourceOptions] = None):
        """
        ## Example Usage
        ### Encrypting with KMS Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplekms = aws.kms.Key("examplekms",
            description="KMS key 1",
            deletion_window_in_days=7)
        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            kms_key_id=examplekms.arn)
        ```
        ### Server Side Encryption with S3 Default Master Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            server_side_encryption="aws:kms")
        ```
        ### Server Side Encryption with AWS-Managed Key

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket")
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("index.html"),
            server_side_encryption="AES256")
        ```
        ### S3 Object Lock

        ```python
        import pulumi
        import pulumi_aws as aws

        examplebucket = aws.s3.BucketV2("examplebucket", object_lock_configuration=aws.s3.BucketV2ObjectLockConfigurationArgs(
            object_lock_enabled="Enabled",
        ))
        example_bucket_acl_v2 = aws.s3.BucketAclV2("exampleBucketAclV2",
            bucket=examplebucket.id,
            acl="private")
        example_bucket_versioning_v2 = aws.s3.BucketVersioningV2("exampleBucketVersioningV2",
            bucket=examplebucket.id,
            versioning_configuration=aws.s3.BucketVersioningV2VersioningConfigurationArgs(
                status="Enabled",
            ))
        example_bucket_object = aws.s3.BucketObject("exampleBucketObject",
            key="someobject",
            bucket=examplebucket.id,
            source=pulumi.FileAsset("important.txt"),
            object_lock_legal_hold_status="ON",
            object_lock_mode="GOVERNANCE",
            object_lock_retain_until_date="2021-12-31T23:59:60Z",
            force_destroy=True,
            opts=pulumi.ResourceOptions(depends_on=[example_bucket_versioning_v2]))
        ```

        ## Import

        Objects can be imported using the `id`. The `id` is the bucket name and the key together e.g.,

        ```sh
         $ pulumi import aws:s3/bucketObject:BucketObject object some-bucket-name/some/key.txt
        ```

         Additionally, s3 url syntax can be used, e.g.,

        ```sh
         $ pulumi import aws:s3/bucketObject:BucketObject object s3://some-bucket-name/some/key.txt
        ```

        :param str resource_name: The name of the resource.
        :param BucketObjectArgs args: The arguments to use to populate this resource's properties.
        :param pulumi.ResourceOptions opts: Options for the resource.
        """
        ...
    def __init__(__self__, resource_name: str, *args, **kwargs):
        resource_args, opts = _utilities.get_resource_args_opts(BucketObjectArgs, pulumi.ResourceOptions, *args, **kwargs)
        if resource_args is not None:
            __self__._internal_init(resource_name, opts, **resource_args.__dict__)
        else:
            __self__._internal_init(resource_name, *args, **kwargs)

    def _internal_init(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 acl: Optional[pulumi.Input[str]] = None,
                 bucket: Optional[pulumi.Input[str]] = None,
                 bucket_key_enabled: Optional[pulumi.Input[bool]] = None,
                 cache_control: Optional[pulumi.Input[str]] = None,
                 content: Optional[pulumi.Input[str]] = None,
                 content_base64: Optional[pulumi.Input[str]] = None,
                 content_disposition: Optional[pulumi.Input[str]] = None,
                 content_encoding: Optional[pulumi.Input[str]] = None,
                 content_language: Optional[pulumi.Input[str]] = None,
                 content_type: Optional[pulumi.Input[str]] = None,
                 etag: Optional[pulumi.Input[str]] = None,
                 force_destroy: Optional[pulumi.Input[bool]] = None,
                 key: Optional[pulumi.Input[str]] = None,
                 kms_key_id: Optional[pulumi.Input[str]] = None,
                 metadata: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 object_lock_legal_hold_status: Optional[pulumi.Input[str]] = None,
                 object_lock_mode: Optional[pulumi.Input[str]] = None,
                 object_lock_retain_until_date: Optional[pulumi.Input[str]] = None,
                 server_side_encryption: Optional[pulumi.Input[str]] = None,
                 source: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]] = None,
                 source_hash: Optional[pulumi.Input[str]] = None,
                 storage_class: Optional[pulumi.Input[str]] = None,
                 tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
                 website_redirect: Optional[pulumi.Input[str]] = None,
                 __props__=None):
        if opts is None:
            opts = pulumi.ResourceOptions()
        if not isinstance(opts, pulumi.ResourceOptions):
            raise TypeError('Expected resource options to be a ResourceOptions instance')
        if opts.version is None:
            opts.version = _utilities.get_version()
        if opts.id is None:
            if __props__ is not None:
                raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource')
            __props__ = BucketObjectArgs.__new__(BucketObjectArgs)

            __props__.__dict__["acl"] = acl
            if bucket is None and not opts.urn:
                raise TypeError("Missing required property 'bucket'")
            if bucket is not None and not opts.urn:
                warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
                pulumi.log.warn("""bucket is deprecated: Use the aws_s3_object resource instead""")
            __props__.__dict__["bucket"] = bucket
            __props__.__dict__["bucket_key_enabled"] = bucket_key_enabled
            __props__.__dict__["cache_control"] = cache_control
            __props__.__dict__["content"] = content
            __props__.__dict__["content_base64"] = content_base64
            __props__.__dict__["content_disposition"] = content_disposition
            __props__.__dict__["content_encoding"] = content_encoding
            __props__.__dict__["content_language"] = content_language
            __props__.__dict__["content_type"] = content_type
            __props__.__dict__["etag"] = etag
            __props__.__dict__["force_destroy"] = force_destroy
            if key is not None and not opts.urn:
                warnings.warn("""Use the aws_s3_object resource instead""", DeprecationWarning)
                pulumi.log.warn("""key is deprecated: Use the aws_s3_object resource instead""")
            __props__.__dict__["key"] = key
            __props__.__dict__["kms_key_id"] = kms_key_id
            __props__.__dict__["metadata"] = metadata
            __props__.__dict__["object_lock_legal_hold_status"] = object_lock_legal_hold_status
            __props__.__dict__["object_lock_mode"] = object_lock_mode
            __props__.__dict__["object_lock_retain_until_date"] = object_lock_retain_until_date
            __props__.__dict__["server_side_encryption"] = server_side_encryption
            __props__.__dict__["source"] = source
            __props__.__dict__["source_hash"] = source_hash
            __props__.__dict__["storage_class"] = storage_class
            __props__.__dict__["tags"] = tags
            __props__.__dict__["website_redirect"] = website_redirect
            __props__.__dict__["tags_all"] = None
            __props__.__dict__["version_id"] = None
        super(BucketObject, __self__).__init__(
            'aws:s3/bucketObject:BucketObject',
            resource_name,
            __props__,
            opts)

    @staticmethod
    def get(resource_name: str,
            id: pulumi.Input[str],
            opts: Optional[pulumi.ResourceOptions] = None,
            acl: Optional[pulumi.Input[str]] = None,
            bucket: Optional[pulumi.Input[str]] = None,
            bucket_key_enabled: Optional[pulumi.Input[bool]] = None,
            cache_control: Optional[pulumi.Input[str]] = None,
            content: Optional[pulumi.Input[str]] = None,
            content_base64: Optional[pulumi.Input[str]] = None,
            content_disposition: Optional[pulumi.Input[str]] = None,
            content_encoding: Optional[pulumi.Input[str]] = None,
            content_language: Optional[pulumi.Input[str]] = None,
            content_type: Optional[pulumi.Input[str]] = None,
            etag: Optional[pulumi.Input[str]] = None,
            force_destroy: Optional[pulumi.Input[bool]] = None,
            key: Optional[pulumi.Input[str]] = None,
            kms_key_id: Optional[pulumi.Input[str]] = None,
            metadata: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
            object_lock_legal_hold_status: Optional[pulumi.Input[str]] = None,
            object_lock_mode: Optional[pulumi.Input[str]] = None,
            object_lock_retain_until_date: Optional[pulumi.Input[str]] = None,
            server_side_encryption: Optional[pulumi.Input[str]] = None,
            source: Optional[pulumi.Input[Union[pulumi.Asset, pulumi.Archive]]] = None,
            source_hash: Optional[pulumi.Input[str]] = None,
            storage_class: Optional[pulumi.Input[str]] = None,
            tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
            tags_all: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None,
            version_id: Optional[pulumi.Input[str]] = None,
            website_redirect: Optional[pulumi.Input[str]] = None) -> 'BucketObject':
        """
        Get an existing BucketObject resource's state with the given name, id, and optional extra
        properties used to qualify the lookup.

        :param str resource_name: The unique name of the resulting resource.
        :param pulumi.Input[str] id: The unique provider ID of the resource to lookup.
        :param pulumi.ResourceOptions opts: Options for the resource.
        :param pulumi.Input[str] acl: [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        :param pulumi.Input[str] bucket: Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        :param pulumi.Input[bool] bucket_key_enabled: Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        :param pulumi.Input[str] cache_control: Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        :param pulumi.Input[str] content: Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        :param pulumi.Input[str] content_base64: Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        :param pulumi.Input[str] content_disposition: Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        :param pulumi.Input[str] content_encoding: Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        :param pulumi.Input[str] content_language: Language the content is in e.g., en-US or en-GB.
        :param pulumi.Input[str] content_type: Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        :param pulumi.Input[str] etag: Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        :param pulumi.Input[bool] force_destroy: Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        :param pulumi.Input[str] key: Name of the object once it is in the bucket.
        :param pulumi.Input[str] kms_key_id: ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] metadata: Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        :param pulumi.Input[str] object_lock_legal_hold_status: [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        :param pulumi.Input[str] object_lock_mode: Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        :param pulumi.Input[str] object_lock_retain_until_date: Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        :param pulumi.Input[str] server_side_encryption: Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        :param pulumi.Input[Union[pulumi.Asset, pulumi.Archive]] source: Path to a file that will be read and uploaded as raw bytes for the object content.
        :param pulumi.Input[str] source_hash: Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        :param pulumi.Input[str] storage_class: [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags: Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        :param pulumi.Input[Mapping[str, pulumi.Input[str]]] tags_all: Map of tags assigned to the resource, including those inherited from the provider `default_tags` configuration block.
        :param pulumi.Input[str] version_id: Unique version ID value for the object, if bucket versioning is enabled.
        :param pulumi.Input[str] website_redirect: Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id))

        __props__ = _BucketObjectState.__new__(_BucketObjectState)

        __props__.__dict__["acl"] = acl
        __props__.__dict__["bucket"] = bucket
        __props__.__dict__["bucket_key_enabled"] = bucket_key_enabled
        __props__.__dict__["cache_control"] = cache_control
        __props__.__dict__["content"] = content
        __props__.__dict__["content_base64"] = content_base64
        __props__.__dict__["content_disposition"] = content_disposition
        __props__.__dict__["content_encoding"] = content_encoding
        __props__.__dict__["content_language"] = content_language
        __props__.__dict__["content_type"] = content_type
        __props__.__dict__["etag"] = etag
        __props__.__dict__["force_destroy"] = force_destroy
        __props__.__dict__["key"] = key
        __props__.__dict__["kms_key_id"] = kms_key_id
        __props__.__dict__["metadata"] = metadata
        __props__.__dict__["object_lock_legal_hold_status"] = object_lock_legal_hold_status
        __props__.__dict__["object_lock_mode"] = object_lock_mode
        __props__.__dict__["object_lock_retain_until_date"] = object_lock_retain_until_date
        __props__.__dict__["server_side_encryption"] = server_side_encryption
        __props__.__dict__["source"] = source
        __props__.__dict__["source_hash"] = source_hash
        __props__.__dict__["storage_class"] = storage_class
        __props__.__dict__["tags"] = tags
        __props__.__dict__["tags_all"] = tags_all
        __props__.__dict__["version_id"] = version_id
        __props__.__dict__["website_redirect"] = website_redirect
        return BucketObject(resource_name, opts=opts, __props__=__props__)

    @property
    @pulumi.getter
    def acl(self) -> pulumi.Output[Optional[str]]:
        """
        [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) to apply. Valid values are `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `bucket-owner-read`, and `bucket-owner-full-control`. Defaults to `private`.
        """
        return pulumi.get(self, "acl")

    @property
    @pulumi.getter
    def bucket(self) -> pulumi.Output[str]:
        """
        Name of the bucket to put the file in. Alternatively, an [S3 access point](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-access-points.html) ARN can be specified.
        """
        return pulumi.get(self, "bucket")

    @property
    @pulumi.getter(name="bucketKeyEnabled")
    def bucket_key_enabled(self) -> pulumi.Output[bool]:
        """
        Whether or not to use [Amazon S3 Bucket Keys](https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) for SSE-KMS.
        """
        return pulumi.get(self, "bucket_key_enabled")

    @property
    @pulumi.getter(name="cacheControl")
    def cache_control(self) -> pulumi.Output[Optional[str]]:
        """
        Caching behavior along the request/reply chain Read [w3c cache_control](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) for further details.
        """
        return pulumi.get(self, "cache_control")

    @property
    @pulumi.getter
    def content(self) -> pulumi.Output[Optional[str]]:
        """
        Literal string value to use as the object content, which will be uploaded as UTF-8-encoded text.
        """
        return pulumi.get(self, "content")

    @property
    @pulumi.getter(name="contentBase64")
    def content_base64(self) -> pulumi.Output[Optional[str]]:
        """
        Base64-encoded data that will be decoded and uploaded as raw bytes for the object content. This allows safely uploading non-UTF8 binary data, but is recommended only for small content such as the result of the `gzipbase64` function with small text strings. For larger objects, use `source` to stream the content from a disk file.
        """
        return pulumi.get(self, "content_base64")

    @property
    @pulumi.getter(name="contentDisposition")
    def content_disposition(self) -> pulumi.Output[Optional[str]]:
        """
        Presentational information for the object. Read [w3c content_disposition](http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) for further information.
        """
        return pulumi.get(self, "content_disposition")

    @property
    @pulumi.getter(name="contentEncoding")
    def content_encoding(self) -> pulumi.Output[Optional[str]]:
        """
        Content encodings that have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. Read [w3c content encoding](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11) for further information.
        """
        return pulumi.get(self, "content_encoding")

    @property
    @pulumi.getter(name="contentLanguage")
    def content_language(self) -> pulumi.Output[Optional[str]]:
        """
        Language the content is in e.g., en-US or en-GB.
        """
        return pulumi.get(self, "content_language")

    @property
    @pulumi.getter(name="contentType")
    def content_type(self) -> pulumi.Output[str]:
        """
        Standard MIME type describing the format of the object data, e.g., application/octet-stream. All Valid MIME Types are valid for this input.
        """
        return pulumi.get(self, "content_type")

    @property
    @pulumi.getter
    def etag(self) -> pulumi.Output[str]:
        """
        Triggers updates when the value changes. The only meaningful value is `filemd5("path/to/file")`. This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"` (see `source_hash` instead).
        """
        return pulumi.get(self, "etag")

    @property
    @pulumi.getter(name="forceDestroy")
    def force_destroy(self) -> pulumi.Output[Optional[bool]]:
        """
        Whether to allow the object to be deleted by removing any legal hold on any object version. Default is `false`. This value should be set to `true` only if the bucket has S3 object lock enabled.
        """
        return pulumi.get(self, "force_destroy")

    @property
    @pulumi.getter
    def key(self) -> pulumi.Output[str]:
        """
        Name of the object once it is in the bucket.
        """
        return pulumi.get(self, "key")

    @property
    @pulumi.getter(name="kmsKeyId")
    def kms_key_id(self) -> pulumi.Output[str]:
        """
        ARN of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the `kms.Key` resource, use the `arn` attribute. If referencing the `kms.Alias` data source or resource, use the `target_key_arn` attribute. This provider will only perform drift detection if a configuration value is provided.
        """
        return pulumi.get(self, "kms_key_id")

    @property
    @pulumi.getter
    def metadata(self) -> pulumi.Output[Optional[Mapping[str, str]]]:
        """
        Map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API).
        """
        return pulumi.get(self, "metadata")

    @property
    @pulumi.getter(name="objectLockLegalHoldStatus")
    def object_lock_legal_hold_status(self) -> pulumi.Output[Optional[str]]:
        """
        [Legal hold](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-legal-holds) status that you want to apply to the specified object. Valid values are `ON` and `OFF`.
        """
        return pulumi.get(self, "object_lock_legal_hold_status")

    @property
    @pulumi.getter(name="objectLockMode")
    def object_lock_mode(self) -> pulumi.Output[Optional[str]]:
        """
        Object lock [retention mode](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-modes) that you want to apply to this object. Valid values are `GOVERNANCE` and `COMPLIANCE`.
        """
        return pulumi.get(self, "object_lock_mode")

    @property
    @pulumi.getter(name="objectLockRetainUntilDate")
    def object_lock_retain_until_date(self) -> pulumi.Output[Optional[str]]:
        """
        Date and time, in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8), when this object's object lock will [expire](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html#object-lock-retention-periods).
        """
        return pulumi.get(self, "object_lock_retain_until_date")

    @property
    @pulumi.getter(name="serverSideEncryption")
    def server_side_encryption(self) -> pulumi.Output[str]:
        """
        Server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`".
        """
        return pulumi.get(self, "server_side_encryption")

    @property
    @pulumi.getter
    def source(self) -> pulumi.Output[Optional[Union[pulumi.Asset, pulumi.Archive]]]:
        """
        Path to a file that will be read and uploaded as raw bytes for the object content.
        """
        return pulumi.get(self, "source")

    @property
    @pulumi.getter(name="sourceHash")
    def source_hash(self) -> pulumi.Output[Optional[str]]:
        """
        Triggers updates like `etag` but useful to address `etag` encryption limitations. Set using `filemd5("path/to/source")`. (The value is only stored in state and not saved by AWS.)
        """
        return pulumi.get(self, "source_hash")

    @property
    @pulumi.getter(name="storageClass")
    def storage_class(self) -> pulumi.Output[str]:
        """
        [Storage Class](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) for the object. Defaults to "`STANDARD`".
        """
        return pulumi.get(self, "storage_class")

    @property
    @pulumi.getter
    def tags(self) -> pulumi.Output[Optional[Mapping[str, str]]]:
        """
        Map of tags to assign to the object. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level.
        """
        return pulumi.get(self, "tags")

    @property
    @pulumi.getter(name="tagsAll")
    def tags_all(self) -> pulumi.Output[Mapping[str, str]]:
        """
        Map of tags assigned to the resource, including those inherited from the provider `default_tags` configuration block.
        """
        return pulumi.get(self, "tags_all")

    @property
    @pulumi.getter(name="versionId")
    def version_id(self) -> pulumi.Output[str]:
        """
        Unique version ID value for the object, if bucket versioning is enabled.
        """
        return pulumi.get(self, "version_id")

    @property
    @pulumi.getter(name="websiteRedirect")
    def website_redirect(self) -> pulumi.Output[Optional[str]]:
        """
        Target URL for [website redirect](http://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html).
        """
        return pulumi.get(self, "website_redirect")


"""
Script for testing on CUB.

Sample usage:
python -m cmr.benchmark.evaluate --split val --name <model_name> --num_train_epoch <model_epoch>
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from absl import app
from absl import flags
import os
import os.path as osp
import numpy as np
import torch
import scipy.io as sio

from ..nnutils import test_utils
from ..data import cub as cub_data
from ..nnutils import predictor as pred_utils

flags.DEFINE_boolean('visualize', False, 'if true visualizes things')

opts = flags.FLAGS

class ShapeTester(test_utils.Tester):
    def define_model(self):
        opts = self.opts

        self.predictor = pred_utils.MeshPredictor(opts)

        # for visualization
        self.renderer = self.predictor.vis_rend
        self.renderer.set_bgcolor([1., 1., 1.])
        self.renderer.renderer.renderer.renderer.image_size = 512
        self.renderer.set_light_dir([0, 1, -1], 0.38)

    def init_dataset(self):
        opts = self.opts
        self.data_module = cub_data

        torch.manual_seed(0)
        self.dataloader = self.data_module.data_loader(opts)

    def evaluate(self, outputs, batch):
        """
        Compute IOU and keypoint error
        """
        opts = self.opts
        bs = opts.batch_size

        ## compute iou
        mask_gt = batch['mask'].view(bs, -1).numpy()
        mask_pred = outputs['mask_pred'].cpu().view(bs, -1).type_as(
            batch['mask']).numpy()
        intersection = mask_gt * mask_pred
        union = mask_gt + mask_pred - intersection
        iou = intersection.sum(1) / union.sum(1)

        # Compute pck
        padding_frac = opts.padding_frac
        # The [-1,1] coordinate frame in which keypoints corresponds to:
        #    (1+2*padding_frac)*max_bbox_dim in image coords
        # pt_norm = 2* (pt_img - trans)/((1+2*pf)*max_bbox_dim)
        # err_pt = 2*err_img/((1+2*pf)*max_bbox_dim)
        # err_pck_norm = err_img/max_bbox_dim = err_pt*(1+2*pf)/2
        # so the keypoint error in the canonical fram should be multiplied by:
        err_scaling = (1 + 2 * padding_frac) / 2.0
        kps_gt = batch['kp'].cpu().numpy()

        kps_vis = kps_gt[:, :, 2]
        kps_gt = kps_gt[:, :, 0:2]
        kps_pred = outputs['kp_pred'].cpu().type_as(batch['kp']).numpy()
        kps_err = kps_pred - kps_gt
        kps_err = np.sqrt(np.sum(kps_err * kps_err, axis=2)) * err_scaling

        return iou, kps_err, kps_vis

    def visualize(self, outputs, batch):
        vert = outputs['verts'][0]
        cam = outputs['cam_pred'][0]
        texture = outputs['texture'][0]

        img_pred = self.renderer(vert, cam, texture=texture)
        aroundz = []
        aroundy = []
        # for deg in np.arange(0, 180, 30):
        for deg in np.arange(0, 150, 30):
            rendz = self.renderer.diff_vp(
                vert, cam, angle=-deg, axis=[1, 0, 0], texture=texture)
            rendy = self.renderer.diff_vp(
                vert, cam, angle=deg, axis=[0, 1, 0], texture=texture)
            aroundz.append(rendz)
            aroundy.append(rendy)

        aroundz = np.hstack(aroundz)
        aroundy = np.hstack(aroundy)
        vps = np.vstack((aroundz, aroundy))

        img = np.transpose(convert2np(batch['img'][0]), (1, 2, 0))
        import matplotlib.pyplot as plt
        plt.ion()
        fig = plt.figure(1)
        ax = fig.add_subplot(121)
        ax.imshow(img)
        ax.set_title('input')
        ax.axis('off')
        ax = fig.add_subplot(122)
        ax.imshow(img_pred)
        ax.set_title('pred_texture')
        ax.axis('off')
        plt.draw()

        fig = plt.figure(2)
        plt.imshow(vps)
        plt.axis('off')
        plt.draw()
        plt.pause(0.01)
        import ipdb
        ipdb.set_trace()

    def test(self):
        opts = self.opts
        bench_stats = {'ious': [], 'kp_errs': [], 'kp_vis': []}

        if opts.ignore_pred_delta_v:
            result_path = osp.join(opts.results_dir, 'results_meanshape.mat')
        elif opts.use_sfm_ms:
            result_path = osp.join(opts.results_dir,
                                   'results_sfm_meanshape.mat')
        else:
            result_path = osp.join(opts.results_dir, 'results.mat')

        if opts.use_sfm_camera:
            result_path = result_path.replace('.mat', '_sfm_camera.mat')

        print('Writing to %s' % result_path)

        if not osp.exists(result_path):

            n_iter = len(self.dataloader)
            for i, batch in enumerate(self.dataloader):
                if i % 100 == 0:
                    print('{}/{} evaluation iterations.'.format(i, n_iter))
                if opts.max_eval_iter > 0 and (i >= opts.max_eval_iter):
                    break
                outputs = self.predictor.predict(batch)
                if opts.visualize:
                    self.visualize(outputs, batch)
                iou, kp_err, kp_vis = self.evaluate(outputs, batch)

                bench_stats['ious'].append(iou)
                bench_stats['kp_errs'].append(kp_err)
                bench_stats['kp_vis'].append(kp_vis)

                if opts.save_visuals and (i % opts.visuals_freq == 0):
                    self.save_current_visuals(batch, outputs)

            bench_stats['kp_errs'] = np.concatenate(bench_stats['kp_errs'])
            bench_stats['kp_vis'] = np.concatenate(bench_stats['kp_vis'])

            bench_stats['ious'] = np.concatenate(bench_stats['ious'])
            sio.savemat(result_path, bench_stats)
        else:
            bench_stats = sio.loadmat(result_path)

        # Report numbers.

        mean_iou = bench_stats['ious'].mean()

        n_vis_p = np.sum(bench_stats['kp_vis'], axis=0)
        n_correct_p_pt1 = np.sum(
            (bench_stats['kp_errs'] < 0.1) * bench_stats['kp_vis'], axis=0)
        n_correct_p_pt15 = np.sum(
            (bench_stats['kp_errs'] < 0.15) * bench_stats['kp_vis'], axis=0)
        pck1 = (n_correct_p_pt1 / n_vis_p).mean()
        pck15 = (n_correct_p_pt15 / n_vis_p).mean()
        print('%s mean iou %.3g, pck.1 %.3g, pck.15 %.3g' %
              (osp.basename(result_path), mean_iou, pck1, pck15))

def main(_):
    opts.n_data_workers = 0
    opts.batch_size = 1

    opts.results_dir = osp.join(opts.results_dir_base, '%s' % (opts.split),
                                opts.name, 'epoch_%d' % opts.num_train_epoch)
    if not osp.exists(opts.results_dir):
        print('writing to %s' % opts.results_dir)
        os.makedirs(opts.results_dir)

    torch.manual_seed(0)
    tester = ShapeTester(opts)
    tester.init_testing()
    tester.test()

if __name__ == '__main__':
    app.run(main)


# -*- coding: utf-8 -*-
"""
Mesa Time Module
================

Objects for handling the time component of a model. In particular, this module
contains Schedulers, which handle agent activation. A Scheduler is an object
which controls when agents are called upon to act, and when.

The activation order can have a serious impact on model behavior, so it's
important to specify it explicitly. Example simple activation regimes include
activating all agents in the same order every step, shuffling the activation
order every time, activating each agent *on average* once per step, and more.

Key concepts:
    Step: Many models advance in 'steps'. A step may involve the activation of
    all agents, or a random (or selected) subset of them. Each agent in turn
    may have their own step() method.

    Time: Some models may simulate a continuous 'clock' instead of discrete
    steps. However, by default, the Time is equal to the number of steps the
    model has taken.

TODO: Have the schedulers use the model's randomizer, to keep random number
seeds consistent and allow for replication.

"""
import random
from collections import OrderedDict

class BaseScheduler:
    """ Simplest scheduler; activates agents one at a time, in the order
    they were added.

    Assumes that each agent added has a *step* method which takes no arguments.

    (This is explicitly meant to replicate the scheduler in MASON).

    """
    def __init__(self, model):
        """ Create a new, empty BaseScheduler. """
        self.model = model
        self.steps = 0
        self.time = 0
        self._agents = OrderedDict()

    def add(self, agent):
        """ Add an Agent object to the schedule.

        Args:
            agent: An Agent to be added to the schedule. NOTE: The agent must
            have a step() method.

        """
        self._agents[agent.unique_id] = agent

    def remove(self, agent):
        """ Remove all instances of a given agent from the schedule.

        Args:
            agent: An agent object.

        """
        del self._agents[agent.unique_id]

    def step(self):
        """ Execute the step of all the agents, one at a time. """
        agent_keys = list(self._agents.keys())
        for agent_key in agent_keys:
            self._agents[agent_key].step()
        self.steps += 1
        self.time += 1

    def get_agent_count(self):
        """ Returns the current number of agents in the queue. """
        return len(self._agents.keys())

    @property
    def agents(self):
        return list(self._agents.values())

class RandomActivation(BaseScheduler):
    """ A scheduler which activates each agent once per step, in random order,
    with the order reshuffled every step.

    This is equivalent to the NetLogo 'ask agents...' and is generally the
    default behavior for an ABM.

    Assumes that all agents have a step(model) method.

    """
    def step(self):
        """ Executes the step of all agents, one at a time, in
        random order.

        """
        agent_keys = list(self._agents.keys())
        random.shuffle(agent_keys)

        for agent_key in agent_keys:
            self._agents[agent_key].step()
        self.steps += 1
        self.time += 1

class SimultaneousActivation(BaseScheduler):
    """ A scheduler to simulate the simultaneous activation of all the agents.

    This scheduler requires that each agent have two methods: step and advance.
    step() activates the agent and stages any necessary changes, but does not
    apply them yet. advance() then applies the changes.

    """
    def step(self):
        """ Step all agents, then advance them. """
        agent_keys = list(self._agents.keys())
        for agent_key in agent_keys:
            self._agents[agent_key].step()
        for agent_key in agent_keys:
            self._agents[agent_key].advance()
        self.steps += 1
        self.time += 1

class StagedActivation(BaseScheduler):
    """ A scheduler which allows agent activation to be divided into several
    stages instead of a single `step` method. All agents execute one stage
    before moving on to the next.

    Agents must have all the stage methods implemented. Stage methods take a
    model object as their only argument.

    This schedule tracks steps and time separately. Time advances in fractional
    increments of 1 / (# of stages), meaning that 1 step = 1 unit of time.

    """
    def __init__(self, model, stage_list=None, shuffle=False,
                 shuffle_between_stages=False):
        """ Create an empty Staged Activation schedule.

        Args:
            model: Model object associated with the schedule.
            stage_list: List of strings of names of stages to run, in the
                         order to run them in.
            shuffle: If True, shuffle the order of agents each step.
            shuffle_between_stages: If True, shuffle the agents after each
                                    stage; otherwise, only shuffle at the start
                                    of each step.

        """
        super().__init__(model)
        self.stage_list = ["step"] if not stage_list else stage_list
        self.shuffle = shuffle
        self.shuffle_between_stages = shuffle_between_stages
        self.stage_time = 1 / len(self.stage_list)

    def step(self):
        """ Executes all the stages for all agents. """
        agent_keys = list(self._agents.keys())
        if self.shuffle:
            random.shuffle(agent_keys)
        for stage in self.stage_list:
            for agent_key in agent_keys:
                getattr(self._agents[agent_key], stage)()  # Run stage
            if self.shuffle_between_stages:
                random.shuffle(agent_keys)
            self.time += self.stage_time

        self.steps += 1