Building a Bookmark Management Workflow
This tutorial walks you through building a complete bookmark management workflow using the BookmarkService. You will learn how to initialize the service, create a new bookmark with validation, organize it into a collection, and retrieve it using full-text search.
Prerequisites
To follow this tutorial, you need the following components from the codebase:
BookmarkServicefromapp.services.bookmark_service- A dictionary of bookmark data (URL and Title are required)
Step 1: Initialize the Bookmark Service
The BookmarkService is implemented as a singleton to ensure that state (like the cache and search index) is shared across your application. You obtain an instance by simply calling the class.
from app.services.bookmark_service import BookmarkService
# Get the singleton instance
service = BookmarkService()
When you initialize the service, it automatically bootstraps the BookmarkRepository, an LRUCache for performance, and the SearchIndex for full-text queries.
Step 2: Create a New Bookmark
The service handles validation for you. When creating a bookmark, you must provide at least a url and a title. The service uses internal validators (_validate_url and _validate_title) to ensure the data is correct before persisting it.
bookmark_data = {
"url": "https://github.com/features/actions",
"title": "GitHub Actions Documentation",
"description": "Learn how to automate your workflow."
}
bookmark, error = service.create_bookmark(bookmark_data)
if error:
print(f"Failed to create bookmark: {error}")
else:
print(f"Created bookmark: {bookmark.id} - {bookmark.title}")
The create_bookmark method returns a tuple: (Bookmark, None) on success or (None, error_message) on failure. On success, the bookmark is automatically saved to the repository and added to the search index.
Step 3: Create a Collection
Collections allow you to group related bookmarks. Like bookmarks, collections are created via the service layer which handles the underlying model instantiation.
collection_data = {
"name": "DevOps Tools",
"type": "manual"
}
collection, error = service.create_collection(collection_data)
if error:
print(f"Failed to create collection: {error}")
else:
print(f"Created collection: {collection.id} ({collection.name})")
By default, collections are manual, meaning you must explicitly add bookmarks to them.
Step 4: Assign the Bookmark to the Collection
Now that you have both a bookmark and a collection, you can link them using their unique IDs.
# Use the IDs from the objects created in previous steps
success = service.add_to_collection(collection.id, bookmark.id)
if success:
print("Bookmark successfully added to collection.")
else:
print("Could not add bookmark. It might already be in the collection.")
The add_to_collection method returns a boolean indicating success. It will return False if the collection ID is invalid or if the bookmark is already present in that collection.
Step 5: Search for the Bookmark
The BookmarkService provides a search method that performs a full-text search across all indexed bookmarks. This is useful for finding your bookmark later without knowing its ID.
# Search for the bookmark we just created
results = service.search("GitHub Actions")
for b in results:
print(f"Found: {b.title} ({b.url})")
The search index is updated automatically whenever create_bookmark or update_bookmark is called, ensuring your search results are always up to date.
Summary
You have successfully:
- Accessed the
BookmarkServicesingleton. - Created a validated
Bookmarkentity. - Created a
Collectionfor organization. - Linked the bookmark to the collection.
- Verified the bookmark is discoverable via full-text search.
For next steps, you can explore service.archive_bookmark(bookmark_id) to manage the lifecycle of your bookmarks or service.create_tag() to add granular metadata.