Skip to main content

Organizing Data with Tags and Collections

Organizing bookmarks in this application is handled through two primary mechanisms: Tags for flat, descriptive labeling and Collections for grouping bookmarks into manual or rule-based sets.

Managing Tags

Tags are used to label bookmarks with metadata like names and colors. The BookmarkService provides the primary interface for managing the tag lifecycle.

Creating and Updating Tags

To create a tag, use the create_tag method. You can specify a name and a color from the TagColor enum.

from app.services.bookmark_service import BookmarkService
from app.models.tag import TagColor

service = BookmarkService()

# Create a new tag
tag_data = {
"name": "Research",
"color": "blue",
"description": "Academic and technical papers"
}
tag, error = service.create_tag(tag_data)

if tag:
print(f"Created tag: {tag.name} (ID: {tag.id})")

Tags can be updated later using update_tag, which allows changing the name or color:

service.update_tag(tag.id, {"color": "purple", "name": "Deep Research"})

Associating Tags with Bookmarks

Tags are associated with bookmarks by storing the tag's ID in the bookmark's tags list. You can set these during bookmark creation or by modifying the bookmark object directly.

# Option 1: Associate during creation
bookmark_data = {
"url": "https://example.com",
"title": "Example",
"tags": [tag.id]
}
bookmark, _ = service.create_bookmark(bookmark_data)

# Option 2: Add to an existing bookmark
bookmark = service.get_bookmark(bookmark_id)
if bookmark.add_tag(tag.id):
# Persist the change via the repository
service._repo.save_bookmark(bookmark)

Filtering Bookmarks by Tag

To retrieve all bookmarks associated with a specific tag, use the get_bookmarks_with_tag method on the BookmarkRepository.

bookmarks = service._repo.get_bookmarks_with_tag(tag.id)
for b in bookmarks:
print(f"Found bookmarked URL: {b.url}")

Deleting Tags and Cleanup

When a tag is deleted via BookmarkService.delete_tag, the service automatically performs a cascading cleanup, removing the tag ID from all associated bookmarks before deleting the tag itself.

# This removes the tag from all bookmarks and then deletes the tag
service.delete_tag(tag.id)

Managing Collections

Collections allow you to group bookmarks. They come in two types: Manual (explicitly managed) and Smart (filter-based).

Manual Collections

Manual collections require you to add or remove bookmarks explicitly using their IDs.

# Create a manual collection
collection_data = {"name": "Project Alpha", "type": "manual"}
collection, _ = service.create_collection(collection_data)

# Add a bookmark to the collection
service.add_to_collection(collection.id, bookmark.id)

# Remove a bookmark
service.remove_from_collection(collection.id, bookmark.id)

Smart Collections

Smart collections use a filter_rule to identify bookmarks. While the Collection model provides a _apply_filter method to match bookmarks based on text in the title or description, these collections do not currently auto-update their bookmark_ids list.

# Create a smart collection for "Python" related bookmarks
smart_data = {
"name": "Python Resources",
"type": "smart",
"filter_rule": "python"
}
smart_collection, _ = service.create_collection(smart_data)

# Internal logic to populate the collection based on the rule
all_bookmarks, _ = service.list_bookmarks()
matching_ids = smart_collection._apply_filter(all_bookmarks)
smart_collection.bookmark_ids = matching_ids
service._repo.save_collection(smart_collection)

Troubleshooting and Limitations

In-Memory Storage

The BookmarkRepository is an in-memory implementation. All tags, collections, and associations will be lost when the application process restarts.

Tag Deletion Performance

The delete_tag operation in BookmarkService iterates through every bookmark that contains the tag to remove the reference. In environments with a very large number of bookmarks per tag, this operation may become performance-intensive as it triggers multiple repository saves and cache invalidations.

Smart Collection Updates

Smart collections do not automatically refresh when new bookmarks are added. You must manually trigger the filtering logic or implement a refresh strategy at the service layer using the _apply_filter helper.