boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
9.01k stars 1.87k forks source link

Having issue uploading an archive to an existing vault via boto3. #2689

Closed newskooler closed 3 years ago

newskooler commented 3 years ago

I am trying to use AWS for the first time and specifically S3 - Glacier. My goal is now to simply upload an archive to an existing vault.

What issue did you see ?

Upon running the code form https://docs.aws.amazon.com/code-samples/latest/catalog/python-glacier-upload_archive.py.html I get the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-174-8fa9dd2fe059> in <module>
     12 
     13 import logging
---> 14 import boto3
     15 from botocore.exceptions import ClientError
     16 

~/miniconda3/lib/python3.7/site-packages/boto3/__init__.py in <module>
     14 import logging
     15 
---> 16 from boto3.session import Session
     17 from boto3.compat import _warn_deprecated_python
     18 

~/miniconda3/lib/python3.7/site-packages/boto3/session.py in <module>
     15 import os
     16 
---> 17 import botocore.session
     18 from botocore.client import Config
     19 from botocore.exceptions import DataNotFoundError, UnknownServiceError

~/miniconda3/lib/python3.7/site-packages/botocore/session.py in <module>
     28 from botocore import UNSIGNED
     29 import botocore.configloader
---> 30 import botocore.credentials
     31 import botocore.client
     32 from botocore.configprovider import ConfigValueStore

~/miniconda3/lib/python3.7/site-packages/botocore/credentials.py in <module>
     32 from botocore.compat import total_seconds
     33 from botocore.compat import compat_shell_split
---> 34 from botocore.config import Config
     35 from botocore.exceptions import UnknownCredentialError
     36 from botocore.exceptions import PartialCredentialsError

~/miniconda3/lib/python3.7/site-packages/botocore/config.py in <module>
     14 from botocore.compat import OrderedDict
     15 
---> 16 from botocore.endpoint import DEFAULT_TIMEOUT, MAX_POOL_CONNECTIONS
     17 from botocore.exceptions import InvalidS3AddressingStyleError
     18 from botocore.exceptions import InvalidRetryConfigurationError

~/miniconda3/lib/python3.7/site-packages/botocore/endpoint.py in <module>
     20 from botocore.vendored import six
     21 
---> 22 from botocore.awsrequest import create_request_object
     23 from botocore.exceptions import HTTPClientError
     24 from botocore.httpsession import URLLib3Session

~/miniconda3/lib/python3.7/site-packages/botocore/awsrequest.py in <module>
     23 from urllib3.connectionpool import HTTPSConnectionPool
     24 
---> 25 import botocore.utils
     26 from botocore.compat import six
     27 from botocore.compat import HTTPHeaders, HTTPResponse, urlunsplit, urlsplit, \

~/miniconda3/lib/python3.7/site-packages/botocore/utils.py in <module>
     31 import botocore
     32 import botocore.awsrequest
---> 33 import botocore.httpsession
     34 from botocore.compat import (
     35         json, quote, zip_longest, urlsplit, urlunsplit, OrderedDict,

~/miniconda3/lib/python3.7/site-packages/botocore/httpsession.py in <module>
     15 try:
     16     # Always import the original SSLContext, even if it has been patched
---> 17     from urllib3.contrib.pyopenssl import orig_util_SSLContext as SSLContext
     18 except ImportError:
     19     from urllib3.util.ssl_ import SSLContext

~/miniconda3/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py in <module>
     85 # Map from urllib3 to PyOpenSSL compatible parameter-values.
     86 _openssl_versions = {
---> 87     util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD,
     88     ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
     89 }

AttributeError: module 'urllib3.util' has no attribute 'PROTOCOL_TLS'

I cannot figure out how to fix this.

Steps to reproduce Try and run this code:

I am using boto3==1.16.34 and urllib3==1.26.2

# Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# This file is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

import logging
import boto3
from botocore.exceptions import ClientError

def upload_archive(vault_name, src_data):
    """Add an archive to an Amazon S3 Glacier vault.

    The upload occurs synchronously.

    :param vault_name: string
    :param src_data: bytes of data or string reference to file spec
    :return: If src_data was added to vault, return dict of archive
    information, otherwise None
    """

    # The src_data argument must be of type bytes or string
    # Construct body= parameter
    if isinstance(src_data, bytes):
        object_data = src_data
    elif isinstance(src_data, str):
        try:
            object_data = open(src_data, 'rb')
            # possible FileNotFoundError/IOError exception
        except Exception as e:
            logging.error(e)
            return None
    else:
        logging.error('Type of ' + str(type(src_data)) +
                      ' for the argument \'src_data\' is not supported.')
        return None

    glacier = boto3.client('glacier')
    try:
        archive = glacier.upload_archive(vaultName=vault_name,
                                         body=object_data)
    except ClientError as e:
        logging.error(e)
        return None
    finally:
        if isinstance(src_data, str):
            object_data.close()

    # Return dictionary of archive information
    return archive

def main():
    """Exercise upload_archive()"""

    # Assign these values before running the program
    test_vault_name = 'VAULT_NAME'
    filename = 'C:\\path\\to\\filename.ext'
    # Alternatively, specify object contents using bytes.
    # filename = b'This is the data to store in the Glacier archive.'

    # Set up logging
    logging.basicConfig(level=logging.DEBUG,
                        format='%(levelname)s: %(asctime)s: %(message)s')

    # Upload the archive
    archive = upload_archive(test_vault_name, filename)
    if archive is not None:
        logging.info(f'Archive {archive["archiveId"]} added to {test_vault_name}')

Debug logs Full stack trace by adding boto3.set_stream_logger('') to your code.

swetashre commented 3 years ago

@snenkov - Thank you for your post. I am not able to reproduce the issue. Looking at this issue https://github.com/urllib3/urllib3/issues/1908 it looks like it might be related to some other module.

I would recommend create a virtual environment and try the code. In this case you would be able to keep your code/dependency separate.

Usama3059 commented 2 years ago

Facing the same issue is there is any solution?