Home

Data Structure Write Up

Introduction

This blog will delve into the complexities of managing collections and databases using Python. It will cover topics such as initializing databases, manipulating tables, and executing CRUD operations efficiently. Additionally, it will explore the process of defining API endpoints with Flask-RESTful and integrating frontend functionalities using JavaScript. Readers can expect to gain insights into backend development, database integration, and API implementation through code snippets, debugging sessions, and visual representations.

Collections


def initializeDatabase():
    global engine, Session, session

    engine = create_engine('sqlite:///database2.db')
    Session = sessionmaker(bind=engine)
    session = Session()

    Base.metadata.create_all(engine)

def clearDatabase():
    initializeDatabase()
    session.query(Images).delete()
    session.commit()
    session.close()

class Images(Base):
    __tablename__ = 'images'
    imageName = Column(String, primary_key=True, nullable=False, unique=False)  # Added nullable=False for primary key
    imageFunc = Column(String, nullable=False, unique=False)  # Added nullable=False for non-nullable columns
    imageBase64 = Column(String, nullable=False, unique=False)

def createImage(name, func, image):
    initializeDatabase()
    newImage = Images(imageName=name, imageFunc=func, imageBase64=image)
    session.add(newImage)
    session.commit()

def initUsers():
    with app.app_context():
        """Create database and tables"""
        db.create_all()
        """Tester data for table"""
        u1 = User(name='Thomas Edison', uid='toby', password='123toby', type="standard")
        u2 = User(name='Imaad Muzaffer', uid='imaad', password='123imaad', type="standard")
        u3 = User(name='Admin Account', uid='admin', type="admin")
        users = [u1, u2, u3]

        """Builds sample user/note(s) data"""
        for user in users:
            try:
                '''add a few 1 to 4 notes per user'''
                '''add user/post data to table'''
                user.create()
            except IntegrityError:
                '''fails with bad or duplicate data'''
                db.session.remove()
                print(f"Records exist, duplicate email, or error: {user.uid}")

APIS and JSON

Blog Python API code and use of Postman to request and respond with JSON.

    # building RESTapi endpoint
    api.add_resource(_CRUD, '/')
    api.add_resource(_Security, '/authenticate')
            # validate name
            name = body.get('name')
            if name is None or len(name) < 2:
                return {'message': f'Name is missing, or is less than 2 characters'}, 400
            # validate uid
            uid = body.get('uid')
            if uid is None or len(uid) < 2:
                return {'message': f'User ID is missing, or is less than 2 characters'}, 400
user = jwt.decode(token, current_app.config["SECRET_KEY"], algorithms=["HS256"])['_uid']

Frontend

const apiUrl = "https://memeforge.stu.nighthawkcodingsociety.com/api/memeforge/get_database";
        let images = [];
        function fetchDatabase() {
            fetch(apiUrl)
                .then(response => response.json())
                .then(response => {
                    if (response.status === 401) {
                        window.location.href = '/student2/login';
                        return;
                    }
                    if (response.status === 403) {
                        window.location.href = '/student2/403';
                        return;
                    }
                    images = JSON.parse(response).reverse();
                    displayImages(images);
                });
        }
function displayImages(images) {
    const gallery = document.querySelector('.gallery');
    gallery.innerHTML = '';
    images.forEach((image, index) => {
        const galleryItemContainer = document.createElement('div');
        galleryItemContainer.className = 'gallery-item-container';
        const galleryItem = document.createElement('div');
        galleryItem.className = 'gallery-item';
        const img = document.createElement('img');
        img.src = 'data:image/jpeg;base64,' + image.image;
        img.alt = image.name;
        img.addEventListener('click', () => {
            openModal(image.image);
        });
        const button = document.createElement('button');
        button.textContent = 'Download';
        button.addEventListener('click', () => {
            downloadImage(image.image, image.name);
        });
        galleryItem.appendChild(img);
        galleryItem.appendChild(button);
        galleryItemContainer.appendChild(galleryItem);
        gallery.appendChild(galleryItemContainer);
    });
}
fetch(url, image_options)
                    .then(response => {
                        if (response.status !== 200) {
                            error('Api error: ' + response.status);
                            return;
                        }
                        response.json().then(data => {
                            const memeImage = new Image();
                            memeImage.src = 'data:image/' + fileExtension + ';base64,' + data['base64image'];
    
                            memeImage.style.maxHeight = '100%';
    
                            uploadedImage.src = memeImage.src;
                            uploadedImage.style.display = 'block';
    
                            memeImage.onload = function () {
                                const parent = document.querySelector('.bottom-half');
                                const ratio = parent.clientWidth / memeImage.width;
    
                                if (ratio < 1) {
                                    const maxHeight = ratio * memeImage.height;
                                    parent.style.height = (maxHeight + 175) + 'px';
                                } else {
                                    parent.style.height = (memeImage.height + 175) + 'px';
                                }
                            };
                        });
                    });
    function handleDownloadClick() {
        const uploadedImage = document.getElementById('uploadedImage');
        const memeImage = new Image();
        memeImage.src = uploadedImage.src;

        if (uploadedImage.width == 0) {
            alert('Please upload an image before trying to download');
            return;
        }
        const downloadLink = document.createElement('a');
        downloadLink.href = memeImage.src;
        downloadLink.download = uploadedImageName.split('.')[0] + "_meme." + uploadedImageName.split('.')[1];
        downloadLink.style.display = 'none';

        document.body.appendChild(downloadLink);
        downloadLink.click();

        document.body.removeChild(downloadLink);

    }
    const downloadButton = document.getElementById('downloadButton');
    downloadButton.addEventListener('click', handleDownloadClick);

Reflection

In summary, we have gone into the complex process of setting up a Python API, focusing on database management and CRUD operations. Through code snippets, it demonstrates the initialization and maintenance of a SQLite database, including table creation, data insertion, and error handling. Flask-RESTful is utilized to define API endpoints, enabling seamless interaction with the database through HTTP methods. Robust data validation mechanisms are implemented to ensure the integrity of input data, while error messages guide users in case of invalid requests. Additionally, the frontend integration is explored using JavaScript, showcasing data fetching and UI updates based on API responses. Visual representations from tools like VSCode and Postman offer insights into debugging sessions and error handling, enhancing the practical understanding of development processes. Security considerations, such as password hashing and JWT token authentication, are implied through code implementations, ensuring the protection of sensitive user data.

© 2024    •  Powered by Soopr   •  Theme  Moonwalk