Managing Tags via Service
To manage tags in this application, use the BookmarkService singleton. This service ensures that tag operations maintain data consistency, such as automatically removing a deleted tag from all associated bookmarks and invalidating relevant caches.
Create a Tag
To create a new tag, pass a dictionary containing the tag details to BookmarkService.create_tag(). The service validates the name and returns a tuple of (Tag, error).
from app.services.bookmark_service import BookmarkService
from app.models.tag import TagColor
service = BookmarkService()
tag_data = {
"name": "Research",
"color": TagColor.BLUE.value,
"description": "Academic and technical papers"
}
tag, error = service.create_tag(tag_data)
if error:
print(f"Failed to create tag: {error}")
else:
print(f"Created tag: {tag.id} ({tag.name})")
Update a Tag
Use BookmarkService.update_tag() to modify an existing tag's name or color. The service handles validation and updates the underlying repository.
from app.services.bookmark_service import BookmarkService
from app.models.tag import TagColor
service = BookmarkService()
# Update tag name and color
update_data = {
"name": "Deep Learning",
"color": TagColor.PURPLE.value
}
tag, error = service.update_tag("tag_id_123", update_data)
if tag:
print(f"Updated tag to: {tag.name} with color {tag.color}")
elif error:
print(f"Validation error: {error}")
else:
print("Tag not found")
Delete a Tag and Cleanup
When you delete a tag via BookmarkService.delete_tag(), the service performs a "strip" operation. It iterates through every bookmark associated with that tag, removes the tag reference, saves the bookmark, and invalidates the cache for each affected bookmark before finally deleting the tag itself.
from app.services.bookmark_service import BookmarkService
service = BookmarkService()
# This will remove the tag from all bookmarks and then delete the tag
success = service.delete_tag("tag_id_123")
if success:
print("Tag deleted and removed from all bookmarks.")
else:
print("Tag not found.")
Listing All Tags
You can retrieve all tags currently stored in the repository using list_tags().
from app.services.bookmark_service import BookmarkService
service = BookmarkService()
tags = service.list_tags()
for tag in tags:
print(f"{tag.name} (Used by {tag.usage_count} bookmarks)")
Validation Rules and Constraints
The BookmarkService enforces several rules defined in app.models._validators and the Tag model:
- Reserved Names: You cannot create tags named
all,untagged,archived, ortrash. - Length Limits: Tag names must be between 1 and 50 characters.
- Unique Colors: Use the
TagColorenum values:RED,BLUE,GREEN,YELLOW,PURPLE, orGRAY.
Troubleshooting
- Performance on Delete: Because
delete_tagiterates through all bookmarks containing that tag to update them, deleting a very popular tag (used by thousands of bookmarks) may be a slow operation as it triggers multiple repository saves and cache invalidations. - Case Sensitivity: Tag names are normalized (stripped and lowercased) during validation to prevent duplicates that differ only by case.
- Usage Counts: While the
Tagmodel includes ausage_countattribute and methods likeincrement_usage(), these are primarily managed by the repository layer when bookmarks are saved or loaded. Avoid manually modifyingusage_countunless you are implementing custom repository logic.