3
\$\begingroup\$

The following program generates the S3 URL and response (status code?) for the key, provided the bucket name and if the S3 URL is a mess (wrong url), then it generates empty string as URL and error as the response.

The code works fine, but the way it handles the messy S3 url seems buggy to me. Please provide some insights to design a better error handling mechanism and a good way to generate the response a.k.a status code?

from boto.s3.connection import S3Connection


class URLGenerator:
    def __init__(self, access_id, access_key, bucket_name, expiry=0):
        """
        Initialization parameters to get url from S3.
        :param access_id: S3 access id
        :param access_key: S3 access key
        :param bucket_name: the name of the bucket to open
        :param expiry: the expiration of the access
        :return: instantiates various attributes
        """
        self.conn = S3Connection(access_id, access_key)
        self.bucket_name = bucket_name
        self.expiry = expiry

    def generate_url(self, k):
        """
        Generates the url by finding the key :param k in the bucket and generates url for it.
        This key is the part of the GET request.
        :param k: the key
        :return: url for the file in S3 and the response for the same,
        """
        resp_dict = {}

        bucket = self.conn.get_bucket(self.bucket_name)

        try:
            key = bucket.get_key(k)
            resp_dict['ok'] = 'success'
            generated_url = key.generate_url(expires_in=self.expiry)
        except AttributeError:
            resp_dict['error'] = "File doesn't exist or check back your S3 URL."
            generated_url = ''
        return generated_url, resp_dict

    def clean_url_and_response(self, id):
        """
        Cleans up the unwanted query methods and authentication tokens in the url generated by
        the self.generate_url() method.
        :param id: the key
        :return: the stripped url and the formatted error or success message based upon the GET request.
        """
        url, resp = self.generate_url(id)
        try:
            url = url.split('?')[0]
        except AttributeError:
            url = ''
        return url, list(resp.values())[0]

    def close(self):
        self.conn.close()
\$\endgroup\$
  • \$\begingroup\$ thank you so much for this piece of code. \$\endgroup\$ – Kiwy Oct 15 '18 at 9:45
1
\$\begingroup\$

Your code is well-written overall, but the users are going to forget to close the url_connection; I would provide automatic closing by implementing the magic methods __enter__ and __exit__ that allow use with with as a context manager.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.