Respectify Python Client
A Python client library for the Respectify API, providing both synchronous and asynchronous interfaces for comment moderation, spam detection, toxicity analysis, and dogwhistle detection.
Respectify aims to be more than comment moderation: it tries to teach and edify users when a comment is rejected.
For bloggers, companies with articles, etc it provides a way to keep discourse civil and on-topic without censorship.
Features
- Supports the full Resepctify feature set for analysing comments and discussion
- Both synchronous (
RespectifyClient) and asynchronous (RespectifyAsyncClient) clients - The Megacall endpoint allows multiple analyses in a single request
Installation
pip install respectify
Quick Start
Synchronous Client
from respectify import RespectifyClient
# Initialize client
client = RespectifyClient(
email="your-email@example.com",
api_key="your-api-key"
)
# Initialize a topic
# Comments on a discussion are in the context of the discussion -- this is any starting material
topic = client.init_topic_from_text("This is my article content")
article_id = topic.article_id
# Evaluate comment quality and toxicity
score = client.evaluate_comment("This is a thoughtful comment", article_id)
print(f"Health: {score.overall_score}/5, Toxicity: {score.toxicity_score:.2f}")
# Comment health: one level per item -- off, relaxed, standard (default), strict, zero_tolerance.
# Threats, identity attacks, sexual content and harassment can only be made stricter.
from respectify import ModerationTolerances, ToleranceLevel
score = client.evaluate_comment("That's a silly take, mate", article_id,
tolerances=ModerationTolerances(insult=ToleranceLevel.RELAXED, quality=ToleranceLevel.OFF))
if score.exceeds_tolerance: # the verdict to act on
for name, item in score.health_items.items():
print(f"{name}: {item.score}/5 (accepts {item.minimum}+)")
# Check if a comment is spam
spam_result = client.check_spam("Great post!", article_id)
print(f"Is spam: {spam_result.is_spam}")
# Perspective-compatible scoring for migrations from Google's Perspective API
perspective = client.perspective.analyze_comment(
{
"comment": {"text": "You clearly did not read the article."},
"requestedAttributes": {
"TOXICITY": {},
"INSULT": {},
},
}
)
print(perspective.attributeScores["TOXICITY"].summaryScore.value)
Asynchronous Client
import asyncio
from respectify import RespectifyAsyncClient
async def main():
client = RespectifyAsyncClient(
email="your-email@example.com",
api_key="your-api-key"
)
# Initialize topic
topic = await client.init_topic_from_text("Article content")
article_id = topic.article_id
# Run multiple analyses concurrently
spam_task = client.check_spam("Great post!", article_id)
score_task = client.evaluate_comment("Thoughtful comment", article_id)
spam_result, score_result = await asyncio.gather(spam_task, score_task)
print(f"Spam: {spam_result.is_spam}, Health: {score_result.overall_score}/5")
asyncio.run(main())
Megacall for Efficiency
Perform multiple analyses in a single API call:
# Instead of multiple separate calls...
result = client.megacall(
comment="Test comment",
article_id=article_id, # pre-registered with init_topic_from_url() (reads a page) or init_topic_from_text() (anything you send it)
include_spam=True,
include_relevance=True,
include_comment_score=True,
include_dogwhistle=True
)
# Access individual results
print(f"Spam: {result.spam.is_spam if result.spam else 'N/A'}")
print(f"Health: {result.comment_score.overall_score if result.comment_score else 'N/A'}/5")
print(f"On topic: {result.relevance.on_topic.is_on_topic if result.relevance else 'N/A'}")
print(f"Dogwhistles: {result.dogwhistle.detection.dogwhistles_detected if result.dogwhistle else 'N/A'}")
API Reference
Available Methods
Topic Management:
init_topic_from_text(text, topic_description=None)- Initialize topic from text contentinit_topic_from_url(url, topic_description=None)- Initialize topic from URL
Comment Analysis:
evaluate_comment(comment, article_id)- Evaluates a comment on logical fallacies, objectionable phrases, negative tone, low effortcheck_relevance(comment, article_id, banned_topics=None)- Relevance and banned topic detectioncheck_dogwhistle(comment, sensitive_topics=None, dogwhistle_examples=None)- Dogwhistle detectioncheck_spam(comment, article_id)- Spam detection
Batch Operations:
megacall(comment, article_id, **options)- Multiple analyses in one call
Perspective Compatibility:
client.perspective.analyze_comment(request)- Public Perspective-compatibleanalyzeCommentclient.perspective.suggest_comment_score(request)- Public Perspective-compatiblesuggestCommentScore
Authentication:
check_user_credentials()- Verify API credentials work without calling any normal API
Response Schemas
All API responses are parsed into strongly-typed Pydantic models:
InitTopicResponse- Topic initialization resultSpamDetectionResult- Spam analysis with confidence scoresCommentScore- Quality metrics and toxicity analysisCommentRelevanceResult- Topic relevance and banned topic detectionDogwhistleResult- Dogwhistle detection with detailed analysisMegaCallResult- Container for multiple analysis resultsUserCheckResponse- Authentication verification result
Error Handling
from respectify import (
RespectifyError, # Base exception
AuthenticationError, # Invalid credentials (401)
BadRequestError, # Invalid parameters (400)
PaymentRequiredError, # Credit balance too low for the call (402)
ServerError # Server issues (500+)
)
try:
result = client.check_spam("test", article_id)
except AuthenticationError:
print("Please check your API credentials")
except PaymentRequiredError:
print("Your credit balance does not cover this call. Add funds to continue.")
except BadRequestError as e:
print(f"Invalid request: {e.message}")
Response Sanitization
All string values in API responses are automatically HTML-encoded to prevent XSS. API responses echo back user-submitted comment text (in quoted fallacies, objectionable phrases, etc.) so this encoding is applied by default to make responses safe to render in HTML.
Configuration
Client Options
client = RespectifyClient(
email="your-email@example.com",
api_key="your-api-key"
)
Development
Running Tests
You will need to provide real Respectify credentials, because this will make calls against the actual API - not a mocked version. Use a key dedicated to testing to separate this from your normal usage.
Create a .env file for testing:
RESPECTIFY_EMAIL=your-email@example.com
RESPECTIFY_API_KEY=your-api-key
REAL_ARTICLE_ID=a-genuine-initialised-article
# Install development dependencies
pip install -e ".[dev]"
# Run tests with real API (requires .env file with real credentials)
pytest tests/ -v
# Run tests with coverage
pytest tests/ --cov=respectify --cov-report=html
Building Documentation
# Install documentation dependencies
pip install -e ".[docs]"
# Build documentation
cd docs
make html
# Serve documentation locally
python -m http.server 8000 --directory _build/html
Code Quality
# Run ruff linting and formatting
ruff check respectify/
ruff format respectify/
# Beartype provides runtime type checking automatically
# Big fans of beartype here
Requirements
- Python 3.9+
- httpx >= 0.24.0
- pydantic >= 2.0.0
- beartype >= 0.15.0
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Documentation: Full API documentation
- Issues: GitHub Issues
- Website: Respectify.ai
Changelog
v0.1.0 (2025-01-XX)
- Initial release
- Synchronous and asynchronous client support
- Complete API coverage for all Respectify endpoints
- Comprehensive type safety with Pydantic schemas
- Megacall support for efficient batch operations
- Full test suite with real API integration
- Sphinx documentation with examples
Metadata
Release files for respectify 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| respectify-0.8.0.tar.gz | 40.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| respectify-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.9 kB
Release files / respectify-0.8.0.tar.gz
| Download URL | respectify-0.8.0.tar.gz |
|---|---|
| Size | 40.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9490aed49da04c939edbe762d63e105f68342097dd72fe468f518dc554a7a263
|
|
BLAKE2b-256 checksum How to use checksums |
50e19a2bfe04923d067a2a54cf29487fb91262d2d4fe98feae1cdcb94ce5a3c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / respectify-0.8.0-py3-none-any.whl
| Download URL | respectify-0.8.0-py3-none-any.whl |
|---|---|
| Size | 22.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d6de22d84c9834262bfc5b7355d85fd5391879c47afd8dbec17562d51a49674
|
|
BLAKE2b-256 checksum How to use checksums |
f5657316856d66c4533fc2b9fa4fd00ca850d5b57d6e5e28b1bca03c9489a42e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|