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_book
s (or new_book
s 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.