Skip to the content.

CB PPR

Requirements:

  • Procedure creation
  • Calling of procedure
  • List (or other collection type) creation
  • Calling of collection type

Procedure:

@suggest_api.route('/bulk', methods=['POST'])
def add_books_bulk():
    data = request.json

    if not isinstance(data, list):
        return jsonify({'error': 'Expected a list of books'}), 400

    results = []

    for book_data in data:
        title = book_data.get('title')
        author = book_data.get('author')
        genre = book_data.get('genre')
        description = book_data.get('description')
        cover_url = book_data.get('cover_url')

        try:
            suggested_book = SuggestedBook(title=title, author=author, genre=genre, description=description, cover_url=cover_url)
            suggested_book.create()
            results.append({'message': 'Book {title} added successfully to suggestions', 'title': title})
        except Exception as e:
            results.append({'error': f'Failed to add book {title}', 'message': str(e), 'title': title})

    return jsonify(results), 201

Breakdown: The function add_books_bulk() sets data equal to the JSONified user’s input and then checks to insure that data is in a list. It initializes the list results to contain the books, then iterates through the data to add the books to the SuggestedBooks database.

Why this code works: It includes selection with the conditional that checks for a list, iteration for creating the books in bulk, and sequencing as the code moves through the function.

Procedure called:

document.getElementById('book-form').addEventListener('submit', async (event) => {
        event.preventDefault();

        const books = Array.from(document.querySelectorAll('.book-entry')).map(entry => ({
            title: entry.querySelector('.title').value,
            author: entry.querySelector('.author').value,
            genre: entry.querySelector('.genre').value,
            description: entry.querySelector('.description').value,
            cover_url: entry.querySelector('.cover_url').value
        }));

        if (books.length === 0) {
            alert('Please add at least one book.');
            return;
        }

        try {
            const response = await fetch(`${pythonURI}/api/suggest/bulk`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(books)
            });

            if (!response.ok) {
                throw new Error(`Failed to add books: ${response.statusText}`);
            }

            const result = await response.json();
            console.log("Books added to suggestions successfully")
            alert('Books added successfully!');
            document.getElementById('book-form').reset();
            fetchBooks();
        } catch (error) {
            console.error('Error adding books to suggestions:', error);
            alert('Error adding books to suggestions: ' + error.message);
        }
    });

Breakdown: This code maps each form input to its corresponding value (title, author, etc.) and ensures that the list length is at least 1. Then it uses the POST method to add the books to the suggestions database.

Why this works: This code calls the add_books_bulk procedure defined in the backend

Collection Type:

@staticmethod
def restore(data):
    restored_books = {}

    for book_data in data:
        _ = book_data.pop('id', None)

        existing_book = SuggestedBook.query.filter_by(title=book_data.get("title")).first()
        if existing_book:
            existing_book.title = book_data.get('title', existing_book.title)
            existing_book.author = book_data.get('author', existing_book.author)
            existing_book.genre = book_data.get('genre', existing_book.genre)
            existing_book.description = book_data.get('description', existing_book.description)
            existing_book.cover_url = book_data.get('cover_url', existing_book.cover_url)
            db.session.commit()
            restored_books[existing_book.id] = existing_book
        else:
            new_book = SuggestedBook(**book_data)
            new_book.create()
            restored_books[new_book.id] = new_book

    return restored_books

Breakdown: restore(data) is a restore function that uses the parameter data and an SQL query to find backed up data (existing_book) and commit it to the database, therefore restoring the books. It initializes the restored_books dictionary to store these books.

Why it works: This code creates a dictionary of books from data using restore() and stores existing_books (or new_books if there are none) in this dicitonary after comitting them to the database.

Collection type used:

from model.suggest import SuggestedBook

def extract_data():
    data = {}
    with app.app_context():
        data['suggestions'] = [suggestion.read() for suggestion in SuggestedBook.query.all()]

    return data

def save_data_to_json(data, directory='backup'):
    if not os.path.exists(directory):
        os.makedirs(directory)
    for table, records in data.items():
        with open(os.path.join(directory, f'{table}.json'), 'w') as f:
            json.dump(records, f)
    print(f"Data backed up to {directory} directory.")

def load_data_from_json(directory='backup'):
    data = {}
    for table in ['suggestions']:
        with open(os.path.join(directory, f'{table}.json'), 'r') as f:
            data[table] = json.load(f)
    return data

def restore_data(data):
    with app.app_context():
        _ = SuggestedBook.restore(data['suggestions'])

    print("Data restored to the new database.")

Breakdown: In main.py, the SuggestedBook class is imported. Using extract_data() and SuggestedBook.query.all(), the suggested book data is stored in data. This is then saved (save_data_to_json(data, directory='backup')) and loaded (load_data_from_json(directory='backup')). Finally, the list from restore(data) is used to restore the SuggestedBook data to the database.

Why this works: This code uses the list initialized in the restore(data) function to restore suggested books to the database.