From 629973145be1ede523bc648c1a4b64a41823d9f2 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Thu, 23 Feb 2023 19:13:15 -0500 Subject: [PATCH] Add S3 functionality --- .gitignore | 1 + src/api/search.py | 33 ++++++++++++--- src/app.py | 3 ++ src/s3Client.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 src/s3Client.py diff --git a/.gitignore b/.gitignore index bda8628..3e646c6 100644 --- a/.gitignore +++ b/.gitignore @@ -181,3 +181,4 @@ tags # Persistent undo [._]*.un~ +apply_environment.sh diff --git a/src/api/search.py b/src/api/search.py index c478996..64f4b90 100644 --- a/src/api/search.py +++ b/src/api/search.py @@ -1,18 +1,39 @@ from flask_restx import Namespace, Resource, fields +from flask_restx import reqparse +import s3Client +import logging +# Exported namespace api = Namespace('search', description='Searching for memes') -query = api.model('Query', { - 'query': fields.String(required=True, description='Search string', example='doge'), +def getClientSafely(): + logging.debug("Getting a client safely...") + client = None + try: + client = s3Client.getClient() + except Exception as e: + logging.critical("Failed to retrive a client : " + str(e)) - }) + return client -@api.route('/exact') + +@api.route('/exact/') @api.doc(params={ 'query': 'Name of the meme you are looking for' }) class exactSearch(Resource): @api.doc('search') - def get(self): - return {"message" : "hello world!"} + @api.response(200, 'Sucess') + @api.response(500, 'S3 Error') + def get(self, query): + logging.debug("Getting a client safely...") + client = getClientSafely() + if client is None: + return { + "message": "Error connecting to S3" + }, 500 + if query in client.getCurrentMemeList(): + return "nice" + else: + return "boo" diff --git a/src/app.py b/src/app.py index 9621b3f..241d34a 100755 --- a/src/app.py +++ b/src/app.py @@ -4,6 +4,9 @@ from flask import Flask from api import api import os +import logging + +logging.basicConfig(level=logging.INFO) isDebug = True diff --git a/src/s3Client.py b/src/s3Client.py new file mode 100644 index 0000000..eeb1f55 --- /dev/null +++ b/src/s3Client.py @@ -0,0 +1,105 @@ +import logging +import os + + + +from minio import Minio +from minio.commonconfig import Tags +from minio.error import S3Error +from datetime import datetime + + +S3_URL = "" +S3_UN = "" +S3_PW = "" +S3_TLS = True +S3_BUCKET = "" + +gclient = None + +def getClient(): + global gclient + global S3_URL + global S3_UN + global S3_PW + global S3_TLS + global S3_BUCKET + if gclient != None: + return gclient + + if "S3_URL" not in os.environ: + raise Exception("S3_URL is not set!") + S3_URL = os.environ["S3_URL"] + logging.info("Using S3_URL : " + S3_URL ) + + + if "S3_UN" not in os.environ: + raise Exception("S3_UN is not set!") + S3_UN = os.environ["S3_UN"] + logging.info("Using S3_UN : " + S3_UN) + + if "S3_PW" not in os.environ: + raise Exception("S3_PW is not set!") + S3_PW = os.environ["S3_PW"] + logging.info("Using S3_PW : " + S3_PW) + + if "S3_BUCKET" not in os.environ: + raise Exception("S3_BUCKET is not set!") + S3_BUCKET = os.environ["S3_BUCKET"] + logging.info("Using S3_BUCKET : " + S3_BUCKET) + + # override defaults + if "S3_TLS" in os.environ: + S3_TLS = os.environ["S3_TLS"].lower() in ("yes", "true", "1", "t") + logging.info("Using S3_TLS : " + str(S3_TLS)) + + client = Minio(S3_URL, + access_key=S3_UN, + secret_key=S3_PW, + secure=S3_TLS) + found = client.bucket_exists(S3_BUCKET) + if not found: + client.make_bucket(S3_BUCKET) + logging.info(f"Failed to find bucket " + S3_BUCKET + " so I made it instead") + else: + logging.info(f"Found bucket " + S3_BUCKET) + + clientObject = Client(client) + gclient = clientObject + + return gclient + +class Client: + allMemes = set() + memesToMd5 = dict() + lastCheckedAllMemes = datetime.strptime("2000-01-01 01:01:01", "%Y-%m-%d %H:%M:%S") + client = None + + def __init__(self, client): + global gclient + if gclient is not None: + raise Exception("Object already exists! use getClient") + logging.debug("Making a new client") + if client is not None: + self.client = client + else: + raise Exception("Improper object passed for client!") + + def getCurrentMemeList(self, force=False): + now = datetime.now() + if (now - self.lastCheckedAllMemes).seconds > 300 or force: + logging.info("Enough time has elapsed, refreshing meme cache...") + self.lastCheckedAllMemes = now + + self.allMemes.clear() + self.memesToMd5.clear() + + for obj in self.client.list_objects(S3_BUCKET): + if not obj.is_dir: + self.allMemes.add(obj.object_name) + self.memesToMd5[obj.etag] = obj.object_name + logging.info("Finished fetching " + str(len(self.allMemes)) + " memes") + + return self.allMemes + + -- 2.45.2