Represents a book in the library system.
Book(title: str, author: str, isbn: str, category: BookCategory = BookCategory.OTHER, publication_year: Optional[int] = None)
Parameters:
title: The title of the bookauthor: The author of the bookisbn: The ISBN number (validated)category: The book category (default: OTHER)publication_year: The publication year (optional)Raises:
InvalidISBNError: If the ISBN is invalidtitle (str): The book’s titleauthor (str): The book’s authorisbn (str): The book’s ISBNcategory (BookCategory): The book’s categorypublication_year (Optional[int]): Publication yearborrower (Optional[Member]): Current borrowerborrowed_date (Optional[datetime]): When the book was borroweddue_date (Optional[datetime]): When the book is dueis_available() -> boolCheck if the book is available for borrowing.
is_overdue() -> boolCheck if the book is overdue.
days_overdue() -> intGet the number of days the book is overdue.
borrow(member: Member, loan_period_days: int = 14) -> NoneMark the book as borrowed by a member.
return_book() -> NoneMark the book as returned.
to_dict() -> dictConvert the book to a dictionary representation.
Represents a library member.
Member(name: str, email: str, member_id: str, max_books: int = 5)
Parameters:
name: The member’s nameemail: The member’s email address (validated)member_id: Unique member identifiermax_books: Maximum books the member can borrow (default: 5)Raises:
InvalidEmailError: If the email is invalidname (str): The member’s nameemail (str): The member’s emailmember_id (str): Unique identifiermembership_date (datetime): When the member joinedmax_books (int): Maximum borrowing limitcan_borrow() -> boolCheck if the member can borrow more books.
borrow_book(book: Book) -> NoneBorrow a book from the library.
Raises:
BookNotAvailableError: If the book is not availableValueError: If the member has reached their borrowing limitreturn_book(book: Book) -> NoneReturn a borrowed book.
Raises:
BookNotBorrowedError: If the book was not borrowed by this memberget_borrowed_books() -> List[Book]Get the list of books currently borrowed.
has_overdue_books() -> boolCheck if the member has any overdue books.
get_overdue_books() -> List[Book]Get the list of overdue books.
calculate_late_fees(fee_per_day: float = 0.50) -> floatCalculate total late fees for overdue books.
get_details() -> strGet a string representation of the member’s details.
to_dict() -> dictConvert the member to a dictionary representation.
Represents the library system.
Library(name: str = "Library")
Parameters:
name: The name of the libraryname (str): The library’s namecreated_date (datetime): When the library was createdadd_book(book: Book) -> NoneAdd a book to the library.
Raises:
DuplicateBookError: If a book with the same ISBN already existsremove_book(isbn: str) -> BookRemove a book from the library.
Raises:
BookNotFoundError: If the book is not foundget_book(isbn: str) -> BookGet a book by ISBN.
Raises:
BookNotFoundError: If the book is not foundfind_books_by_title(title: str, exact: bool = False) -> List[Book]Find books by title.
find_books_by_author(author: str, exact: bool = False) -> List[Book]Find books by author.
find_books_by_category(category: BookCategory) -> List[Book]Find books by category.
get_all_books() -> List[Book]Get all books in the library.
get_available_books() -> List[Book]Get all available books.
get_borrowed_books() -> List[Book]Get all borrowed books.
get_overdue_books() -> List[Book]Get all overdue books.
add_member(member: Member) -> NoneAdd a member to the library.
Raises:
DuplicateMemberError: If a member with the same ID already existsremove_member(member_id: str) -> MemberRemove a member from the library.
Raises:
MemberNotFoundError: If the member is not foundValueError: If the member has borrowed booksget_member(member_id: str) -> MemberGet a member by ID.
Raises:
MemberNotFoundError: If the member is not foundfind_members_by_name(name: str, exact: bool = False) -> List[Member]Find members by name.
get_all_members() -> List[Member]Get all members in the library.
get_members_with_overdue_books() -> List[Member]Get all members with overdue books.
get_statistics() -> Dict[str, int]Get library statistics.
Returns a dictionary containing:
total_books: Total number of booksavailable_books: Number of available booksborrowed_books: Number of borrowed booksoverdue_books: Number of overdue bookstotal_members: Total number of membersmembers_with_overdue: Number of members with overdue booksto_dict() -> dictConvert the library to a dictionary representation.
Service for persisting library data to JSON files.
StorageService(storage_path: Optional[Path] = None)
Parameters:
storage_path: Path to storage file (default: ./data/library_data.json)save_library(library: Library) -> NoneSave the library data to a JSON file.
Raises:
IOError: If there’s an error writing to the fileload_library() -> Optional[Library]Load library data from a JSON file.
Returns:
Raises:
IOError: If there’s an error reading from the fileValueError: If the data is invaliddelete_storage() -> NoneDelete the storage file.
storage_exists() -> boolCheck if the storage file exists.
Configuration settings for the library system.
Settings(
library_name: str = "City Library",
max_books_per_member: int = 5,
loan_period_days: int = 14,
late_fee_per_day: float = 0.50,
storage_path: str = "data/library_data.json"
)
load_from_file(config_path: Path) -> SettingsLoad settings from a JSON configuration file.
load_or_default(config_path: Optional[Path] = None) -> SettingsLoad settings from a file or return default settings.
save_to_file(config_path: Path) -> NoneSave settings to a JSON configuration file.
Base exception class for all library-related exceptions.
Raised when attempting to borrow a book that is not available.
Raised when a requested book is not found in the library.
Raised when a requested member is not found in the library.
Raised when an invalid ISBN is provided.
Raised when an invalid email address is provided.
Raised when attempting to add a book that already exists.
Raised when attempting to add a member that already exists.
Raised when attempting to return a book that was not borrowed by the member.
from library_system import Library, Book, Member, BookCategory
# Create library
library = Library("My Library")
# Add a book
book = Book("1984", "George Orwell", "9780451524935", BookCategory.FICTION, 1949)
library.add_book(book)
# Add a member
member = Member("John Doe", "john@example.com", "M001")
library.add_member(member)
# Borrow a book
member.borrow_book(book)
# Return a book
member.return_book(book)
from pathlib import Path
from library_system import Library, Book, Member
from library_system.services import StorageService
from library_system.config import Settings
# Load settings
settings = Settings.load_or_default(Path("config/library_config.json"))
# Create storage service
storage = StorageService(Path(settings.storage_path))
# Load or create library
library = storage.load_library() or Library(settings.library_name)
# ... perform operations ...
# Save library
storage.save_library(library)