From 7761debc5bcf60bf938aa566ed6a4e37909efb84 Mon Sep 17 00:00:00 2001 From: nolan Date: Sat, 2 Dec 2023 17:40:04 -0800 Subject: [PATCH] initial commit --- .gitignore | 23 +++++ README.md | 1 + lib_afc_s3storage/__init__.py | 8 ++ lib_afc_s3storage/afs3exception.py | 6 ++ lib_afc_s3storage/s3storage.py | 147 +++++++++++++++++++++++++++++ setup.cfg | 15 +++ 6 files changed, 200 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 lib_afc_s3storage/__init__.py create mode 100644 lib_afc_s3storage/afs3exception.py create mode 100755 lib_afc_s3storage/s3storage.py create mode 100644 setup.cfg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c078a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +venv/ +test-venv/ + +*.pyc +__pycache__/ + +instance/ + +.pytest_cache/ +.coverage +htmlcov/ + +dist/ +build/ +*.egg-info/ + +node_modules/ + +.envs +session_files/ +mongo_data/ +test_data/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..02958c8 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Library AF S3 Storage diff --git a/lib_afc_s3storage/__init__.py b/lib_afc_s3storage/__init__.py new file mode 100755 index 0000000..b26240d --- /dev/null +++ b/lib_afc_s3storage/__init__.py @@ -0,0 +1,8 @@ +""" +lib_afc_s3storage +--------------------------------------------- +A Python library for managing S3 object storage +""" + +from lib_afc_s3storage.s3storage import S3Storage +from lib_afc_s3storage.afs3exception import AFS3Error diff --git a/lib_afc_s3storage/afs3exception.py b/lib_afc_s3storage/afs3exception.py new file mode 100644 index 0000000..4bcb7fa --- /dev/null +++ b/lib_afc_s3storage/afs3exception.py @@ -0,0 +1,6 @@ +""" +AF S3 Custom exceptions +""" + +class AFS3Error(Exception): + """AFS3Error class. Custom Exception object.""" diff --git a/lib_afc_s3storage/s3storage.py b/lib_afc_s3storage/s3storage.py new file mode 100755 index 0000000..892f354 --- /dev/null +++ b/lib_afc_s3storage/s3storage.py @@ -0,0 +1,147 @@ +""" +S3Storage Class object +""" + +import os +import logging + +import boto3 + +from lib_afc_s3storage.afs3exception import AFS3Error + + +class S3Storage: + """ + S3Storage class + """ + + def __init__( self, access_key=None, secret_access_key=None, data_center="us-lax-1" ): + """ + __init__ Init S3 Storage class. + + :param access_key: S3 Bucket access key + :param secret_access_key: S3 Bucket secret key + :param data_center: S3 Bucket data center. Default us-lax-1 + """ + + self.access_key = access_key + self.secret_access_key = secret_access_key + self.data_center = data_center + + self.client = None + + if self.access_key is not None and self.secret_access_key is not None: + self.connect() + + + def connect( self ): + """ + connect + """ + + # generate an error if keys are empty + + linode_obj_config = { + "aws_access_key_id": self.access_key, + "aws_secret_access_key": self.secret_access_key, + "endpoint_url": f"https://{self.data_center}.linodeobjects.com", + } + self.client = boto3.client("s3", **linode_obj_config) + + + def connect_data_center( self, data_center ): + """ + connect_data_center + """ + + # "us-southeast-1" = Atlanta, GA + # "us-ord-1" = Chicago, IL + # "us-lax-1" = Los Angeles, CA + # "us-mia-1" = Miami, FL + # "us-east-1" = Newark, NJ + # "us-sea-1" = Seattle, WA + # "us-iad-1" = Washington, DC + + self.data_center = data_center + if self.access_key is not None and self.secret_access_key is not None: + self.connect() + + + def list_buckets( self ): + """ + list_buckets + """ + + if self.client is None: + return None + + r = self.client.list_buckets() + logging.debug("response keys = %s", str(r.keys())) + + return r['Buckets'] + + + def list_objects( self, bucket=None ): + """ + list_objects + """ + + if self.client is None or bucket is None: + return None + + r = self.client.list_objects(Bucket=bucket) + + return r['Contents'] + + + def upload_file( self, filepathname=None, bucket=None, key=None ): + """ + upload_file + """ + + if filepathname is None: + raise AFS3Error("S3Storage.upload_file(): missing required filepathname") + elif not os.path.exists(filepathname): + raise AFS3Error("S3Storage.upload_file(): invalid filepathname '%s'", filepathname) + + if bucket is None: + raise AFS3Error("S3Storage.upload_file(): missing required bucket name") + + if key is None: + raise AFS3Error("S3Storage.upload_file(): missing required key name") + + self.client.upload_file(Filename=filepathname, + Bucket=bucket, + Key=key, + ExtraArgs={'ACL': 'public-read'}) + + + def upload_folder( self ): + """ + upload_folder + """ + return + + + def get_object( self, bucket=None, filename=None ): + """ + get_object + """ + + if bucket is None: + raise AFS3Error("S3Storage.get_object(): missing required bucket name") + + if filename is None: + raise AFS3Error("S3Storage.get_object(): missing required filename") + + this_object = self.client.get_object(Bucket=bucket, Key=filename) + + return this_object['Body'] + + + def delete_objects( self ): + """ + delete_objects + """ + + return diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..3adc277 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,15 @@ +[metadata] +name = lib_afc_s3storage +version = 0.1.0 +author = '' +author_email = '' +description = '' +long_description = file: README.md + +[options] +zip_safe = False +include_package_data = False +packages = find: +python_requires = >=3.7 +install_requires = + boto3==1.33.6