Your First Bookmark
In this tutorial, you will learn how to use the core entities of the kaisen99-etchblok-test-api-f5f8018 codebase to create a bookmark, organize it with tags, and group it into a collection.
By the end of this guide, you will have a fully initialized Bookmark instance that is persisted in the repository, associated with a custom Tag, and filed under a Collection.
Prerequisites
To follow this tutorial, you need to have the BookmarkService initialized. Since BookmarkService is a singleton, you can simply instantiate it.
from app.services.bookmark_service import BookmarkService
# Initialize the service (this bootstraps the repository and search index)
service = BookmarkService()
Step 1: Create a Bookmark
The primary way to create a bookmark is through the BookmarkService.create_bookmark method. This method handles URL validation and automatically indexes the content for search.
bookmark_data = {
"url": "https://github.com/features/actions",
"title": "GitHub Actions",
"description": "Automate your workflow from idea to production"
}
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. If the URL is invalid (e.g., doesn't start with http) or the title is missing, it returns an error message. On success, it returns the Bookmark instance, which now has a unique 12-character ID.
Step 2: Create and Assign a Tag
Tags allow you to categorize bookmarks across different collections. We will create a "DevOps" tag with a specific color and attach it to our bookmark.
from app.models.tag import TagColor
tag_data = {
"name": "DevOps",
"color": "blue",
"description": "Tools for CI/CD and automation"
}
tag, error = service.create_tag(tag_data)
if tag:
# Attach the tag to the bookmark
bookmark.add_tag(tag.id)
# Increment the tag's usage count
tag.usage_count += 1
# Persist the changes
service._repo.save_bookmark(bookmark)
service._repo.save_tag(tag)
print(f"Tagged bookmark with: {tag.name}")
When creating a tag, the name must be unique and cannot be a reserved word like "all" or "untagged". The TagColor enum provides preset values like RED, BLUE, GREEN, etc.
Step 3: Grouping in a Collection
Collections are used to group related bookmarks. We will create a manual collection and add our bookmark to it.
collection_data = {
"name": "Work Tools",
"type": "manual"
}
collection, error = service.create_collection(collection_data)
if collection:
# Add the bookmark to the collection using the service
success = service.add_to_collection(collection.id, bookmark.id)
if success:
print(f"Added bookmark to collection: {collection.name}")
The service.add_to_collection method ensures that the collection exists and is a MANUAL type. If you try to add a bookmark to a SMART collection manually, the operation will return False.
Step 4: Verifying the Result
You can now verify the state of your objects by converting them to dictionaries, which is how they are typically sent to the frontend via the API.
import json
# View the bookmark with its associated tag ID
print(json.dumps(bookmark.to_dict(), indent=2))
# View the collection with the bookmark ID in its list
print(json.dumps(collection.to_dict(), indent=2))
Important Considerations
- Reserved Names: You cannot name a tag
all,untagged,archived, ortrash. - Smart Collections: If you set a collection's type to
smart, you must provide afilter_rule. Smart collections automatically include bookmarks based on that rule and do not allow manual additions. - Persistence: Always use the
BookmarkServicemethods where possible, as they handle cache invalidation and search indexing automatically. If you modify model attributes directly (likebookmark.add_tag), you must manually call the repository's save methods.
Next Steps
Now that you've created your first bookmark, you can explore:
- Archiving: Use
service.archive_bookmark(bookmark.id)to move it out of your active list. - Search: Use
service.search("GitHub")to find your bookmark using the full-text search index. - Smart Collections: Create a collection with
type="smart"andfilter_rule="GitHub"to see it auto-populate.