trustcafe-api-wrapper/docs/WRAPPERS.md
Jezza Hehn e7cf4f1e09 docs: fix parameter mismatches and inaccurate documentation
- Fix update_post() wrapper documentation (post_id -> post_text/post_path/post_key)
- Fix create_comment() wrapper documentation (added post_slug, post_key parameters)
- Add missing wrapper docs for follow(), trust(), votecast(), react()
- Fix reaction job parameters (parent_id -> parent_sk, corrected payload structure)
- Fix trust job parameters (updated to match actual payload structure)
- Fix vote job parameters (voteType -> vote, added parent structure)
- Clearly mark Block and Mute jobs as NOT IMPLEMENTED
- Fix GitLab URLs to Forgejo (git.jezzahehn.com)
- Remove LLM-style language (comprehensive -> full/thorough)
- Fix trust listbyusersinit parameter (username -> user_id)
2026-04-18 02:47:33 +00:00

728 lines
17 KiB
Markdown

# TrustCafé API Wrapped Functions Guide
This guide covers the high-level wrapper functions provided by the TrustCafé API wrapper. Wrappers simplify common operations by handling payload preparation and job execution automatically.
## Table of Contents
- [Overview](#overview)
- [Post Wrappers](#post-wrappers)
- [Comment Wrappers](#comment-wrappers)
- [Wrappers Best Practices](#wrappers-best-practices)
- [Wrapper vs Job](#wrapper-vs-job)
## Overview
### What are Wrappers?
Wrappers are pre-built functions that encapsulate common TrustCafé API operations. They:
- **Simplify usage**: Less boilerplate code
- **Handle payload preparation**: Automatically structure requests
- **Prevent errors**: Built-in validation and defaults
- **Self-documenting**: Clear parameter names and descriptions
### When to Use Wrappers
**Use Wrappers for:**
- Creating and managing content (posts, comments)
- Standard operations with predictable inputs
- Reducing code complexity
- Frequently used patterns
**Use Jobs or Custom Requests when:**
- More control is needed
- Custom parameter combinations
- Operations not covered by wrappers
- Uncommon workflows
### Quick Example
```python
# Using a wrapper (RECOMMENDED)
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.wrapped(create_post(
"This is my post content",
parent_path="/music"
))
# Using a job (for custom control)
API.run_job('post.create', {
"postText": "Different content",
"parent": {
"pk": "parents-key",
"sk": "parents-key"
}
})
```
## Post Wrappers
### create_post()
Creates a new post with simplified parameters.
```python
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.wrapped(create_post(
post_text="Post content here",
parent_path="/branch-name",
blur_label=None,
card_url=None,
collaborative=False
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `post_text` | str | **Required** | The text content of the post |
| `parent_path` | str | `"/"` | Branch path where the post will be created |
| `blur_label` | str | `None` | Optional label for blurring content |
| `card_url` | str | `None` | Optional URL for card preview |
| `collaborative` | bool | `False` | Enable collaborative editing |
**Returns:** dict - Job execution result, contains success information
**Example - Basic Post:**
```python
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.handle_token()
API.wrapped(create_post(
"Welcome to TrustCafé!",
parent_path="/"
))
```
**Example - Post in a Specific Branch:**
```python
API.wrapped(create_post(
"Music discussion thread",
parent_path="/music",
blur_label=None,
card_url=None,
collaborative=False
))
```
**Example - Blurred Post:**
```python
API.wrapped(create_post(
"Sensitive information",
parent_path="/",
blur_label="secret", # Will blur until labeled
card_url=None,
collaborative=False
))
```
**Example - Collaborative Post:**
```python
API.wrapped(create_post(
"Research paper draft - collaborative editing",
parent_path="/research",
blur_label=None,
card_url=None,
collaborative=True # Enables real-time collaboration
))
```
Example of performing multi-step integration with create_post and a linked resource:
```python
# Create post
created = API.wrapped(create_post("Paper title / author", parent_path="/research"))
# If response includes pk/sk, attach a linked item (structure depends on TrustCafé's link feature)
API.run_job('some.link.create', {
"fromPK": "paper",
"fromSK": created.get('pk'),
"toPK": "external-source",
"toSK": created.get('sk')
})
```
### update_post()
Updates an existing post.
```python
from trustcafeapiwrapper.wrappers.post.update_post import update_post
API.wrapped(update_post(
post_text="New post content",
post_path="my-post-slug", # OR use post_key
parent_path="/"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `post_text` | str | **Required** | The new post content |
| `post_path` | str | `None` | The slug of the post to update |
| `parent_path` | str | `'/'` | Parent path for the post |
| `post_key` | dict | `None` | Direct pk/sk dict if you have it |
| `blur_label` | str | `None` | Optional blur label for content |
| `card_url` | str | `None` | Optional URL for link preview card |
| `collaborative` | bool | `False` | Enable collaborative editing |
**Returns:** dict - Job specification for update operation
**Important:** You must provide either `post_key` OR both `post_path` and `parent_path`.
**Example - Update with Path:**
```python
from trustcafeapiwrapper.wrappers.post.update_post import update_post
API.handle_token()
API.wrapped(update_post(
post_text="Updated content here",
post_path="my-post-slug",
parent_path="/music"
))
```
**Example - Update with Key:**
```python
API.wrapped(update_post(
post_text="Updated with key",
post_key={"pk": "post#123", "sk": "post#123"}
))
```
**Example - Update with Blur:**
```python
API.wrapped(update_post(
post_text="Sensitive content",
post_path="my-post",
parent_path="/",
blur_label="nsfw"
))
```
See update_post.py for full implementation details.
## Comment Wrappers
### create_comment()
Creates a new comment on a post.
```python
from trustcafeapiwrapper.wrappers.comment.create_comment import create_comment
# Option 1: Using post_key
API.wrapped(create_comment(
comment_text="This is a comment",
post_key={"pk": "post#123", "sk": "post#123"}
))
# Option 2: Using parent_path + post_slug
API.wrapped(create_comment(
comment_text="This is a comment",
parent_path="/userprofile/my-username",
post_slug="my-post-slug"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `comment_text` | str | **Required** | The comment content |
| `post_slug` | str | `None` | Slug of the post to comment on (required if not using post_key) |
| `parent_path` | str | `None` | Path in format `'userprofile/slug'` or `'subwiki/slug'` |
| `post_key` | dict | `None` | Direct pk/sk dict for the post |
| `blur_label` | str | `None` | Optional blur label for content |
| `version` | int | `3` | Comment structure version |
**Returns:** dict - Job specification for create operation
**Important:** You must provide either `post_key` OR both `parent_path` AND `post_slug`.
**Example - Using post_key:**
```python
from trustcafeapiwrapper.wrappers.comment.create_comment import create_comment
API.handle_token()
API.wrapped(create_comment(
comment_text="Great post! I really enjoyed reading it.",
post_key={"pk": "post#abc123", "sk": "post#abc123"}
))
```
**Example - Using parent_path and post_slug:**
```python
API.wrapped(create_comment(
comment_text="I agree with your point.",
parent_path="/userprofile/philosopher-jon",
post_slug="my-thoughts-on-truth"
))
```
**Example - With blur label:**
```python
API.wrapped(create_comment(
comment_text="Spoiler content warning.",
parent_path="/subwiki/movies",
post_slug="movie-review",
blur_label="spoiler"
))
```
## Wrappers Best Practices
### 1. Provide Context in Parent Paths
**Good - Explicit paths:**
```python
API.wrapped(create_post(
"Content",
parent_path="/music/discussion" # Clear and specific
))
```
**Bad - Empty paths:**
```python
API.wrapped(create_post(
"Content",
parent_path="/" # Default root - less clear intention
))
```
### 2. Handle Phone Numbers in Content
When phone numbers appear in text, leave them as-is. The API wraps the input string, so `555-1234` stays `555-1234`. No HTML is added.
### 3. Path Normalization
Paths are used directly without extra normalization:
```python
# Use with leading slash
API.wrapped(create_post(
"Content",
parent_path="/music"
))
# Or without (both should work)
API.wrapped(create_post(
"Content",
parent_path="music"
))
```
### 4. Validate Parent Exists
It's good practice to verify the parent path exists:
```python
# Check if branch exists
branches = API.run_job('branch.listbyname', "music")
if branches.get('Items'):
# Branch exists, proceed with post
API.wrapped(create_post(
"Content",
parent_path="/music"
))
else:
print("Branch 'music' does not exist")
```
### 5. Handle Responses
```python
from trustcafeapiwrapper.wrappers.post.create_post import create_post
response = API.wrapped(create_post(
"My post",
parent_path="/music"
))
# Check for success
if response and 'success' in response:
print("Post created successfully!")
print(f"Post ID: {response.get('pk')}")
else:
print("Failed to create post")
print(f"Error: {response.get('error')}")
```
### 6. Error Handling
```python
from trustcafeapiwrapper.wrappers.post.create_post import create_post
import logging
logger = logging.getLogger(__name__)
try:
API.handle_token() # Ensure authenticated
API.wrapped(create_post(
"Post content",
parent_path="/music"
))
logger.info("Post created successfully")
except Exception as e:
logger.error(f"Failed to create post: {e}")
# Handle error - maybe retry, notify admin, etc.
```
## Wrapper vs Job
| Feature | Wrappers | Jobs |
|---------|----------|------|
| **Simplicity** | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| **Flexibility** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| **Default Values** | ✅ Yes | ❌ No |
| **Parameter Validation** | ✅ Yes | ❌ No |
| **Common Operations** | ✅ Many | ❌ None |
| **Custom Operations** | ❌ No | ✅ Yes |
| **Learning Curve** | Low | High |
### Replacement Examples
**Example 1: Create Post**
```python
# Wrapper - Simple
API.wrapped(create_post(
"Content",
parent_path="/music"
))
# Job - More complex
API.run_job('post.create', {
"postText": "Content",
"parent": {
"pk": "encode(parent_path)",
"sk": "encode(parent_path)"
}
})
```
**Example 2: Update Post**
```python
# Wrapper
API.wrapped(update_post(
post_id="current-pk-same-as-sk",
new_post_text="New content"
))
# Job
API.run_job('post.update', {
"pk": "current-pk-same-as-sk",
"sk": "current-pk-same-as-sk",
"newPostText": "New content"
})
```
**Example 3: Create Comment**
```python
# Wrapper
API.wrapped(create_comment(
"My comment",
parent_path="/post-id"
))
# Job
API.run_job('comment.create', {
"commentText": "My comment",
"parent": {
"pk": "post-id",
"sk": "post-id"
}
})
```
### When to Use Each
**Use Wrappers When:**
- Common operation (create/update post/comment)
- Multiple optional parameters
- Want concise, readable code
- Acceptable default behavior
**Use Jobs When:**
- Rarely used operation
- Very specific parameter combinations
- Custom job names unsupported by wrappers
- Need maximum flexibility
## Creating Custom Wrappers
You can create your own wrappers for repeated operations:
```python
# Custom post wrapper
def create_in_branch(API, branch: str, content: str, create_card: bool = False):
"""
Helper wrapper for creating posts in specific branches.
Args:
API: The APIClient instance
branch: Branch name (e.g., "music", "science")
content: Post content
create_card: Whether to create a card URL
Returns:
dict: API response
"""
card_url = "https://example.com/card" if create_card else None
from trustcafeapiwrapper.wrappers.post.create_post import create_post
return API.wrapped(create_post(
content,
parent_path=f"/{branch}",
card_url=card_url
))
# Usage
API.handle_token()
result = create_in_branch(API, "music", "New music discussion")
# Or with card
result = create_in_branch(API, "science", "Research paper abstract", create_card=True)
```
## Follow Wrappers
### follow()
Follow or unfollow a user or subwiki.
```python
from trustcafeapiwrapper.wrappers.follow.follow import follow
API.wrapped(follow(
entity="userprofile",
is_following=True,
parent_slug="philosopher-jon"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `entity` | str | **Required** | Type of entity: `'userprofile'` or `'subwiki'` |
| `is_following` | bool | **Required** | `True` to follow, `False` to unfollow |
| `parent_slug` | str | **Required** | Slug of the user or subwiki to follow |
**Returns:** dict - Job specification for follow operation
**Example - Follow a user:**
```python
from trustcafeapiwrapper.wrappers.follow.follow import follow
API.handle_token()
API.wrapped(follow(
entity="userprofile",
is_following=True,
parent_slug="philosopher-jon"
))
```
**Example - Unfollow a subwiki:**
```python
API.wrapped(follow(
entity="subwiki",
is_following=False,
parent_slug="music"
))
```
---
## Trust Wrappers
### trust()
Set trust level for a user.
```python
from trustcafeapiwrapper.wrappers.trust.trust import trust
API.wrapped(trust(
trustLevel="trusted",
userprofile_path="/userprofile/philosopher-jon"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `trustLevel` | str | **Required** | Trust level to set (e.g., `'trusted'`, `'neutral'`, `'distrusted'`) |
| `userprofile_path` | str | **Required** | Path to the user profile |
**Returns:** dict - Job specification for trust operation
**Example:**
```python
from trustcafeapiwrapper.wrappers.trust.trust import trust
API.handle_token()
API.wrapped(trust(
trustLevel="trusted",
userprofile_path="/userprofile/some-user"
))
```
---
## Vote Wrappers
### votecast()
Cast a vote on a post or comment.
```python
from trustcafeapiwrapper.wrappers.vote.votecast import votecast
# Option 1: Using item_key
API.wrapped(votecast(
vote="up",
item_key={"pk": "post#123", "sk": "post#123"}
))
# Option 2: Using parent_path and item_path
API.wrapped(votecast(
vote="down",
parent_path="/userprofile/my-username",
item_path="my-post-slug"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `vote` | str | **Required** | Vote type: `'up'` or `'down'` |
| `parent_path` | str | `None` | Parent path (required if not using item_key) |
| `item_path` | str | `None` | Item slug (required if not using item_key) |
| `item_key` | dict | `None` | Direct pk/sk dict for the item |
**Returns:** dict - Job specification for vote operation
**Example - Upvote with key:**
```python
from trustcafeapiwrapper.wrappers.vote.votecast import votecast
API.handle_token()
API.wrapped(votecast(
vote="up",
item_key={"pk": "post#abc", "sk": "post#abc"}
))
```
**Example - Downvote with paths:**
```python
API.wrapped(votecast(
vote="down",
parent_path="/subwiki/politics",
item_path="controversial-post"
))
```
---
## Reaction Wrappers
### react()
React to a post or comment.
```python
from trustcafeapiwrapper.wrappers.reaction.react import react
# Option 1: Using item_key
API.wrapped(react(
reaction_type="like",
item_key={"pk": "post#123", "sk": "post#123"}
))
# Option 2: Using parent_path and item_path
API.wrapped(react(
reaction_type="heart",
parent_path="/userprofile/my-username",
item_path="my-post-slug"
))
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `reaction_type` | str | **Required** | Type of reaction (e.g., `'like'`, `'heart'`, `'fire'`) |
| `parent_path` | str | `None` | Parent path (required if not using item_key) |
| `item_path` | str | `None` | Item slug (required if not using item_key) |
| `item_key` | dict | `None` | Direct pk/sk dict for the item |
**Returns:** dict - Job specification for reaction operation
**Important:** You must provide either `item_key` OR both `parent_path` AND `item_path`.
**Example:**
```python
from trustcafeapiwrapper.wrappers.reaction.react import react
API.handle_token()
API.wrapped(react(
reaction_type="fire",
item_key={"pk": "post#123", "sk": "post#123"}
))
```
---
## Summary
Wrappers provide a convenient, safe way to perform common operations with the TrustCafé API. For most use cases, wrappers reduce boilerplate and prevent configuration errors. However, jobs offer greater flexibility when standard wrappers don't meet your needs.
**Choose wisely:**
- Wrappers for standard operations and simplicity
- Jobs for custom operations and maximum control
- Custom wrappers for repeated patterns
---
## Next Steps
- [API Reference](api_reference.md) - Complete list of all API jobs
- [Custom Requests Guide](custom_requests.md) - Making advanced API calls manually
- [Examples](../README.md#examples) - Real-world usage examples