Skip to main content

Official Python client for the SentiSift comment-moderation and intelligence API.

Reason this release was yanked:

HealthResponse.progress had wrong shape; use 0.1.1 which fixes the model and matches the live API

Project description

SentiSift Python SDK

Official Python client for the SentiSift comment-moderation and intelligence API.

What SentiSift does. Send a batch of comments and an article, receive bot/spam flags, sentiment labels, commercial-content flags, and confidence scores. On paid tiers, also get crowd-level Intelligence (discussion themes, Omega Ratio) and interleaved Influence comments when a discussion skews negative.

Install

pip install sentisift

Requires Python 3.9 or newer.

Quick start

from sentisift import SentiSift

client = SentiSift()  # reads SENTISIFT_API_KEY from env
result = client.analyze(
    article_url="https://example.com/article/1",
    comments=[
        {"text": "Great article, very informative!", "author": "alice", "time": "2026-04-18T10:00:00"},
        {"text": "This is wrong on so many levels.", "author": "bob", "time": "2026-04-18T10:05:00"},
    ],
    article_text="The full article body goes here...",  # recommended on the first batch only
    title="My Article Title",
)

if result.status == "buffered":
    print(f"Buffered {result.buffered_count}/{result.threshold} comments - not yet analyzed")
elif result.status == "processed":
    for comment in result.comments:
        tag = " (SentiSift)" if comment.is_influence else ""
        print(f"{comment.sentiment_label:<12} {comment.text}{tag}")
    print(f"Balance: {result.comment_balance} comments remaining")

Get a free API key (1,000 comments, no credit card) at sentisift.com/pricing.

Core concepts

  • Buffered batching. Small batches are buffered per article until a processing threshold is reached. Below-threshold requests return status="buffered" with no billing. Above-threshold requests return status="processed" with analysis results for all accumulated comments for that article.
  • Article text on first batch. Send article_text on the first batch for each article (we cache it and use it for contextual analysis). Skip it on later batches for the same article.
  • URL normalization. https://example.com/a and https://EXAMPLE.COM/a/ map to the same article.
  • Deduplication. Comments are deduplicated by (author, text, time), so overlapping batches are safe.

Full details: sentisift.com/api-docs.html.

Configuration

client = SentiSift(
    api_key="sk_sentisift_...",            # or set SENTISIFT_API_KEY env var
    base_url="https://api.sentisift.com",  # override for testing
    timeout=30.0,                          # per-request timeout in seconds
    max_retries=3,                         # retries on 429 and 503
    user_agent="my-app/1.0",               # override default (keep version visible)
)

Handling responses

from sentisift import BufferedResponse, ProcessedResponse

result = client.analyze(article_url=..., comments=...)

if isinstance(result, BufferedResponse):
    # Nothing to render yet. Keep collecting.
    ...
elif isinstance(result, ProcessedResponse):
    # Render every entry in result.comments in order.
    # Influence comments (on Pro/Enterprise) are flagged with is_influence=True.
    for c in result.comments:
        render(c.text, c.sentiment_label, c.composite_score, is_influence=c.is_influence)

    # Intelligence is only populated on Professional and Enterprise.
    if result.intelligence:
        print(result.intelligence.discussion_themes)
        print(f"Mood: {result.intelligence.omega_interpretation} ({result.intelligence.omega_ratio:+.2f})")

Error handling

Every SDK exception exposes the docs_url from the API response for self-service debugging.

from sentisift import (
    SentiSiftError,
    SentiSiftAuthError,
    SentiSiftValidationError,
    SentiSiftRateLimitError,
    SentiSiftServiceLoadingError,
    SentiSiftServerError,
)

try:
    client.analyze(...)
except SentiSiftValidationError as err:
    print(f"Payload invalid: {err.message}")
    print(f"Docs: {err.docs_url}")      # deep link to the exact field row
    print(f"Request ID: {err.request_id}")
except SentiSiftRateLimitError as err:
    print(f"Rate limited. Retry in {err.retry_after}s.")
except SentiSiftAuthError:
    print("Invalid API key.")
except SentiSiftServiceLoadingError:
    print("Models still loading; try again shortly.")
except SentiSiftError as err:
    print(f"Unexpected error: {err}")

The SDK automatically retries on HTTP 429 (respecting Retry-After) and HTTP 503 (models loading). You only see these exceptions if every retry attempt has been exhausted.

Other endpoints

# Balance, grants, subscription state, influence stats
usage = client.get_usage()
print(f"{usage.comment_balance} comments remaining on {usage.tier} tier")
for grant in usage.comment_grants:
    print(f"  {grant.comments_remaining}/{grant.comments_granted} expires {grant.expires_at}")

# Retrieve already-processed results for an article
result = client.get_results(article_url="https://example.com/article")

# Service readiness
health = client.get_health()
if health.status == "loading":
    client.wait_until_ready(timeout=60)

Testing

# In your tests, inject an httpx.Client for mocking
import httpx
import respx
from sentisift import SentiSift

@respx.mock
def test_my_integration():
    respx.post("https://api.sentisift.com/api/v1/analyze").mock(
        return_value=httpx.Response(200, json={...})
    )
    client = SentiSift(api_key="sk_test")
    result = client.analyze(...)

Versioning

This SDK follows semantic versioning. Before 1.0.0, minor versions may include breaking changes (documented in CHANGELOG.md). Pin a version in production:

sentisift>=0.1,<0.2

Links

License

Proprietary. See project terms at sentisift.com/terms.html.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentisift-0.1.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sentisift-0.1.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file sentisift-0.1.0.tar.gz.

File metadata

  • Download URL: sentisift-0.1.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for sentisift-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2574e377c1cb515937717ef9f3029a3ff8416930075610d39d6859466848b721
MD5 8d093c1c75574b43cc68b8131b057cb4
BLAKE2b-256 6ed2e0a6789c615f492840eebdd2bbf274a0d1ad135b9d8809a0611c7bdcf0da

See more details on using hashes here.

File details

Details for the file sentisift-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sentisift-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for sentisift-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4018e32cad279112a31d2803ed9403688d60f55fc9f805b0c874d35eafca6ced
MD5 3f7be09ff06ff0b53d40290dcf30c34d
BLAKE2b-256 0d1d8f61134a50f1f7dbb3dd9862aa7d104aae7d486f3fb76770067ad4d0d1a8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page