Skip to main content

Building a Bookmark Library

In this tutorial, you will learn how to build a functional bookmark library using the core components of the vik-advani-etchblok-test-api-7ee56a2 codebase. You will create bookmarks, categorize them with tags, and organize them into both manual and smart collections.

Prerequisites

To follow this tutorial, you need to interact with the BookmarkService, which is the primary public interface for all business logic in this project. It is implemented as a singleton.

from app.services.bookmark_service import BookmarkService

# Initialize the service
service = BookmarkService()

Step 1: Creating Your First Bookmark

The foundation of your library is the Bookmark model. To create one, you pass a dictionary of attributes to the service. The url and title fields are required.

bookmark_data = {
"url": "https://docs.python.org",
"title": "Python Documentation",
"description": "The official documentation for the Python programming language."
}

bookmark, error = service.create_bookmark(bookmark_data)

if error:
print(f"Failed to create bookmark: {error}")
else:
print(f"Created bookmark: {bookmark.title} (ID: {bookmark.id})")

The create_bookmark method validates the URL format and title length before persisting the bookmark to the repository and indexing it for search.

Step 2: Organizing with Tags

Tags allow you to label bookmarks across different categories. Each Tag has a name and a TagColor.

Creating a Tag

When creating a tag, you can choose from several colors: RED, BLUE, GREEN, YELLOW, PURPLE, or GRAY.

from app.models.tag import TagColor

tag_data = {
"name": "Programming",
"color": TagColor.BLUE.value,
"description": "Resources related to software development"
}

tag, error = service.create_tag(tag_data)

if error:
print(f"Error: {error}")

Note: Certain tag names are reserved by the system and cannot be used: all, untagged, archived, and trash.

Attaching Tags to Bookmarks

You can associate tags with a bookmark during creation by providing a list of tag IDs.

dev_tag, _ = service.create_tag({"name": "Development", "color": "green"})

new_bookmark, _ = service.create_bookmark({
"url": "https://github.com",
"title": "GitHub",
"tags": [dev_tag.id]
})

Step 3: Grouping into Collections

Collections provide a higher level of organization. This project supports two types of collections: Manual and Smart.

Manual Collections

A manual collection requires you to explicitly add bookmarks by their ID.

from app.models.collection import CollectionType

# 1. Create a manual collection
collection, _ = service.create_collection({
"name": "Daily Reads",
"type": CollectionType.MANUAL.value
})

# 2. Add a bookmark to it
success = service.add_to_collection(collection.id, bookmark.id)

if success:
print(f"Added '{bookmark.title}' to '{collection.name}'")

Smart Collections

Smart collections use a filter_rule to automatically include bookmarks. If the rule keyword appears in a bookmark's title or description, it is included in the collection dynamically.

# Create a smart collection that finds anything related to 'Python'
smart_col, _ = service.create_collection({
"name": "Python Stuff",
"type": CollectionType.SMART.value,
"filter_rule": "python"
})

print(f"Smart collection '{smart_col.name}' created with rule: {smart_col.filter_rule}")

You cannot manually add bookmarks to a smart collection; the add_to_collection method will return False if attempted.

Step 4: Managing the Bookmark Lifecycle

As your library grows, you may want to move items out of your active view without deleting them entirely.

Archiving

Archiving moves a bookmark to the ARCHIVED status.

archived_bookmark = service.archive_bookmark(bookmark.id)
print(f"Status: {archived_bookmark.status.value}") # Output: archived

Trashing and Restoring

If you no longer need a bookmark, you can "trash" it (a soft-delete). Trashed bookmarks can be restored later.

# Move to trash
service.delete_bookmark(bookmark.id)

# Restore to active status
service.restore_bookmark(bookmark.id)

Summary

You have successfully built a basic bookmark library. You can now:

  1. Create Bookmarks with validated URLs.
  2. Label them with Tags using custom colors.
  3. Organize them into Manual Collections for specific lists.
  4. Use Smart Collections to automate organization based on keywords.
  5. Manage the lifecycle of your data using Archive and Trash states.

For next steps, explore the service.search(query) method to perform full-text searches across your growing library.