chore: add comprehensive API wrapper documentation

- Add docs/ directory with 6 comprehensive documentation files:
  * INDEX.md - Main navigation and documentation index
  * GETTING_STARTED.md - Setup and configuration guide
  * API_REFERENCE.md - Complete API documentation
  * WRAPPERS.md - High-level wrappers guide
  * CUSTOM_REQUESTS.md - Advanced usage patterns
  * TROUBLESHOOTING.md - Problem-solving guide

- Update README.md with enhanced project information

- Update development.md with expanded documentation context

Extends previous session's documentation work with complete
developer and user-facing documentation.

Closes previous documentation issue.
This commit is contained in:
BarnacleBoy 2026-04-18 01:44:49 +00:00
parent 14346ed02e
commit fd1a1566e9
8 changed files with 4909 additions and 61 deletions

628
README.md
View file

@ -1,52 +1,632 @@
# Trustcafe API Wrapper
# TrustCafé API Wrapper
A Python wrapper for the TrustCafé API, providing a convenient interface to interact with TrustCafé features programmatically.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Authentication](#authentication)
- [API Reference](#api-reference)
- [Jobs](#jobs)
- [Wrappers](#wrappers)
- [Custom Requests](#custom-requests)
- [Environment Setup](#environment-setup)
- [Debug Mode](#debug-mode)
- [Examples](#examples)
- [Development](#development)
- [Testing](#testing)
## Prerequisites
You will need:
1. API Client and Secret
2. Python 3.11 or something sensible or above
3. A method for environment variables like [python-dotenv](https://pypi.org/project/python-dotenv/)
Before you begin, ensure you have:
### API client key and secret from the site
- **Python 3.11 or higher** installed
- **API Client ID and Secret** from TrustCafé
- **python-dotenv** (for `.env` file support) or ability to set environment variables
### Getting API Credentials
1. Visit your TrustCafé account page:
- [Production API Access](https://www.trustcafe.io/en/myaccount/apiaccess)
- [Alpha Environment API Access](https://alpha.wts2.net/en/myaccount/apiaccess)
1. https://www.trustcafe.io/en/myaccount/apiaccess for production and https://alpha.wts2.net/en/myaccount/apiaccess for alpha (this will change in the future)
2. Click "Create new client credentials key pair"
3. Choose all of the scopes or select which you would like to restrict the key to
4. Scroll down and press Save
5. Copy the client key and secret to your environment, the secret cannot be retrieved without making a new one
3. Choose the scopes you need (or select all for full access)
4. Click "Save"
5. Copy the **client_id** and **client_secret** to your environment:
- The secret cannot be retrieved later — make sure to save it securely
- Do not commit these credentials to version control
## Installation
```bash
# Using pip
pip install trustcafeapiwrapper
OR
# Using uv (recommended)
uv add trustcafeapiwrapper
```
## Usage
## Quick Start
The simplest way to get started:
```python
import trustcafeapiwrapper, os
import trustcafeapiwrapper
import os
# Initialize the API client
API = trustcafeapiwrapper.APIClient(
client_id=os.getenv("client_id"),
client_secret=os.getenv("client_secret"),
env="alpha" # alpha | production.
client_id=os.getenv("TRUSTCAFE_CLIENT_ID"),
client_secret=os.getenv("TRUSTCAFE_CLIENT_SECRET"),
env="alpha", # Options: "alpha" or "production"
debug=False
)
profile = API.run_job('userprofile.get', "simon-little")
# Authenticate and get user profile
API.handle_token()
profile = API.run_job('userprofile.get', "your-username")
print(profile)
```
## Authentication
The API wrapper handles OAuth2 client-credentials authentication automatically.
### Automatic Token Management
```python
API.handle_token()
```
**What it does:**
- Checks for an existing token file (`token_data_{env}.json`)
- If found, verifies if the token is still valid
- If expired or not found, obtains a new access token (~3 month duration)
- Saves the token to a local file for future requests
### Manual Token Management
For more control over token storage:
```python
def getMyToken():
# Retrieve token from your custom storage (database, file, etc.)
return {
"access_token": "your_token_here",
"access_token_timeout": 9999999999 # Unix timestamp
}
def saveMyToken(token_data):
# Save to your preferred storage
with open("my_token_cache.json", "w") as f:
json.dump(token_data, f)
return True
# Set the token manually or pass to initialize
API = APIClient(
client_id=os.getenv("client_id"),
client_secret=os.getenv("client_secret"),
env="production",
debug=False
)
# Use existing token or get a new one
if not API.is_token_valid():
saveMyToken(API.sign_in())
```
### Token Validation
```python
if API.is_token_valid():
print("Token is valid")
else:
API.handle_token() # Get a new token
```
## Environment Setup
The wrapper supports two environments:
| Environment | URL | Purpose |
|------------|-----|---------|
| `alpha` | `alpha.wts2.net` | Development/staging environment |
| `production` | `trustcafe.io` | Production environment |
```python
# Alpha environment (default)
API = APIClient(
client_id="your-client-id",
client_secret="your-client-secret",
env="alpha",
debug=False
)
# Production environment
API = APIClient(
client_id="your-client-id",
client_secret="your-client-secret",
env="production",
debug=False
)
# Change environment dynamically
API.set_environment("production")
```
## API Reference
### Jobs
Jobs are pre-built functions that map to specific API endpoints. They return the raw response from the API.
#### Post Operations
```python
# Get a specific post
post = API.run_job('post.get', "post-slug-or-id")
# Create a post
post = API.run_job('post.create', {
"postText": "This is a test post",
"parent": {
"pk": "maintrunk#maintrunk",
"sk": "maintrunk#maintrunk"
}
})
# List all posts
posts = API.run_job('post.listall')
# List public posts
public_posts = API.run_job('post.listpublic')
# List posts by a specific branch
branch_posts = API.run_job('post.listbybranch', "branch-name")
# List posts by a user profile
user_posts = API.run_job('post.listbyuserprofile', "username")
# Update a post
updated_post = API.run_job('post.update', {
"pk": "post-id",
"sk": "post-id",
"newPostText": "Updated text"
})
# Delete a post
deleted = API.run_job('post.listremoved', "post-id")
```
#### Comment Operations
```python
# Create a comment
comment = API.run_job('comment.create', {
"commentText": "This is a comment",
"parent": {
"pk": "post-id",
"sk": "post-id"
}
})
# Get comments by post ID
comments = API.run_job('comment.listtbypostid', "post-id")
```
#### User Profile Operations
```python
# Get user profile
profile = API.run_job('userprofile.get', "username")
```
#### Follow Operations
```python
# Follow a user
followed = API.run_job('follow.follow', "username-to-follow")
```
#### Vote Operations
```python
# Cast a vote
voted = API.run_job('vote.votecast', {
"pk": "post-id",
"sk": "post-id",
"voteType": "up" # or "down"
})
```
#### Reaction Operations
```python
# React to something (post, comment, etc.)
reactions = API.run_job('reaction.reacttosomething', {
"objectPK": "post-id",
"objectSK": "post-id",
"objectType": "post",
"reactionType": "like" # various types supported
})
# Get reactions by parent
post_reactions = API.run_job('reaction.getbyparent', "parent-id")
# List reactions
reactions_list = API.run_job('reaction.listbyparent', "parent-id")
```
#### Notification Operations
```python
# List all notifications
notifications = API.run_job('notification.listnotifications')
# Mark all as read
API.run_job('notification.markallasread')
```
#### Trust Operations
```python
# Create or update trust relationship
trust = API.run_job('trust.createorupdate', {
"pk": "trust_id",
"sk": "trust_id",
"trustType": "positive"
})
# List trust by user initialization
trusts = API.run_job('trust.listbyusersinit', "username")
# List trust by user has
trusts = API.run_job('trust.listbyuserhas', "username")
```
#### Branch Operations
```python
# Get a specific branch
branch = API.run_job('branch.get', "branch-name")
# List branches by name
branches = API.run_job('branch.listbyname', "prefix")
```
#### Feed Operations
```python
# Get café feed
feed = API.run_job('feed.cafefeed')
# Get following feed
following_feed = API.run_job('feed.following')
```
#### Block Operations
```python
# Block a user (function exists but needs implementation)
# TODO: Add job function for block operations
```
#### Mute Operations
```python
# Mute functionality (to be added)
# TODO: Add job function for mute operations
```
### Wrappers
Wrappers are high-level functions that simplify common operations by handling payload preparation and job execution automatically.
#### Using a Wrapper
```python
API.handle_token()
# Create a post with a wrapper (recommended for simplicity)
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.wrapped(create_post(
"This is a test post created via the create_post wrapper function.",
"This is a test post created via the wrapper.",
parent_path="/", # Root path (optional)
blur_label=None, # Optional blurring
card_url=None, # Optional card URL
collaborative=False # Optional collaboration flag
))
# Create a comment
from trustcafeapiwrapper.wrappers.comment.create_comment import create_comment
API.wrapped(create_comment(
"This is a comment",
parent_path="/" # Parent path (required)
))
```
## More
- [Development "Things to think about do"](https://gitlab.com/trustcafe/trustcafe-api-wrapper/-/blob/main/development.md)
- [Documentation](https://gitlab.com/trustcafe/trustcafe-api-wrapper/-/blob/main/documentation.md)
**About Wrappers:**
- Wrappers simplify common operations
- They prepare the payload and job execution automatically
- More wrappers are being added for consistency
- For flexibility, use Jobs or Custom Requests
### Using `run_job` vs. Wrappers
| Feature | `run_job` | Wrappers |
|---------|----------|----------|
| Simplicity | Higher | Highest for common tasks |
| Flexibility | Maximum | Optimized for specific use cases |
| Discovery | Need to know job format | Self-documenting payloads |
| Customization | Full control | Pre-defined options |
**Recommendation:**
- Use **Wrappers** for common, well-documented operations
- Use **Jobs** when you need fine-grained control
- Use **Custom Requests** when neither fits your needs
## Custom Requests
For operations not covered by jobs or wrappers, use the `make_request` method:
```python
# Make a raw API request
response = API.make_request(
method="GET",
endpoint="content",
path="post/some-custom-path",
authenticate=True,
query_params={"param1": "value1"}
)
```
**Parameters:**
- `method` (str): HTTP method - "GET", "POST", "PUT", "DELETE"
- `endpoint` (str): API endpoint - "content", "auth", "audrey", etc.
- `path` (str): API path after endpoint
- `authenticate` (bool): Whether to include authentication token
- `query_params` (dict): Optional query parameters
**Example - Custom Request:**
```python
# Get posts from a specific branch with filters
posts = API.make_request(
"GET",
"content",
"post/ref-subwiki/music",
query_params={"limit": 10, "offset": 0}
)
```
## Debug Mode
Enable debug mode to see all API requests and responses:
```python
API = APIClient(
client_id=os.getenv("client_id"),
client_secret=os.getenv("client_secret"),
env="production",
debug=True # Enable debug mode
)
# Now API calls will print request details
API.handle_token()
```
## Examples
### Example 1: Basic Post Creation
```python
import trustcafeapiwrapper
import os
# Setup
API = trustcafeapiwrapper.APIClient(
client_id=os.getenv("TRUSTCAFE_CLIENT_ID"),
client_secret=os.getenv("TRUSTCAFE_CLIENT_SECRET"),
env="alpha",
debug=False
)
# Handle authentication
API.handle_token()
# Create a post in the music branch
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.wrapped(create_post(
"New music discussion post",
parent_path="/music",
blur_label=None,
card_url=None,
collaborative=False
))
```
### Example 2: Following a User and Getting Their Profile
```python
import trustcafeapiwrapper
import os
API = trustcafeapiwrapper.APIClient(
client_id=os.getenv("TRUSTCAFE_CLIENT_ID"),
client_secret=os.getenv("TRUSTCAFE_CLIENT_SECRET"),
env="production"
)
# Follow a user
follow = API.run_job('follow.follow', "philosopher-jon")
print(f"Followed user: {follow}")
# Get their profile
profile = API.run_job('userprofile.get', "philosopher-jon")
print(f"Profile data: {profile}")
```
### Example 3: Managing Notifications
```python
import trustcafeapiwrapper
import os
API = trustcafeapiwrapper.APIClient(
client_id=os.getenv("TRUSTCAFE_CLIENT_ID"),
client_secret=os.getenv("TRUSTCAFE_CLIENT_SECRET"),
env="production"
)
API.handle_token()
# Check for new notifications
notifications = API.run_job('notification.listnotifications')
print(f"Unread notifications: {notifications}")
# Mark all as read
API.run_job('notification.markallasread')
print("All notifications marked as read")
```
### Example 4: Creating a Collaborative Post
```python
import trustcafeapiwrapper
import os
API = trustcafeapiwrapper.APIClient(
client_id=os.getenv("TRUSTCAFE_CLIENT_ID"),
client_secret=os.getenv("TRUSTCAFE_CLIENT_SECRET"),
env="production"
)
API.handle_token()
# Create a collaborative post
from trustcafeapiwrapper.wrappers.post.create_post import create_post
API.wrapped(create_post(
"Research paper draft - collaborative editing",
parent_path="/research",
collaborative=True # Enables collaborative editing
))
```
## Development
### Project Structure
```
trustcafe-api-wrapper/
├── src/
│ └── trustcafeapiwrapper/
│ ├── apiclient.py # Core API client
│ ├── jobs/ # API job functions
│ │ ├── post/
│ │ ├── comment/
│ │ ├── userprofile/
│ │ ├── follow/
│ │ └── ... (all jobs)
│ ├── wrappers/ # High-level wrappers
│ │ ├── post/
│ │ ├── comment/
│ │ └── ...
│ └── utils/ # Helper functions
├── tests/ # Test files
├── README.md # This file
├── documentation.md # Basic documentation
├── development.md # Project notes
└── pyproject.toml # Project configuration
```
### Adding New Jobs
1. Create a new file in `src/trustcafeapiwrapper/jobs/`
2. Define a function matching the job name
3. Export it from the module's `__init__.py`
4. Document the parameters and return value
**Example - Adding a Job:**
```python
# src/trustcafeapiwrapper/jobs/example/new_job.py
def my_new_job(API, param1: str, param2: int) -> dict:
"""
Create a new job function.
Args:
API: The APIClient instance
param1 (str): Description of parameter 1
param2 (int): Description of parameter 2
Returns:
dict: The API response
"""
response = API.make_request(
"POST",
"endpoint",
"path/to/resource",
data={"param1": param1, "param2": param2}
)
return response
```
### Known Limitations
- **Incomplete Jobs**: Not all available API endpoints have wrapper functions yet
- **Enums**: Some enum types are not strictly typed
- **Block Operations**: Block functionality exists in backend but not yet exposed
- **Mute Operations**: Mute functionality pending implementation
### Future Enhancements
- Complete coverage of all TrustCafé API endpoints
- Type hints for better IDE support
- Async support for better performance
- Comprehensive test suite
- Pydantic models for request/response validation
## Testing
Run the test suite:
```bash
pytest
```
Or run specific tests:
```bash
# Test the API client
python -m pytest tests/apiclient.py
# Run all tests
python -m pytest tests/
```
## License
[Depends on TrustCafé project license]
## Support
For issues, questions, or contributions:
- [TrustCafé Website](https://trustcafe.io)
- [GitLab Repository](https://gitlab.com/trustcafe/trustcafe-api-wrapper)
- Contact the WikiTribune team
## Version History
- **0.1.0.13** - Current version with ongoing development
---
**Note:** This wrapper is for internal WikiTribune/TrustCafé use. Public API endpoints are subject to change.