Skip to content
RSFlowHub
Developer docs API v1 Stable OpenAPI SDKs Playground
Python SDK for the RSFlowHub AI API (sync & async)

Python SDK

The official Python library for the RSFlowHub AI API, with sync and async clients. Add sentiment analysis, translation, chat, PII redaction, knowledge-base search and chatbots to Django, FastAPI, Flask, Celery jobs, scripts and notebooks.

Direct System Definition: RSFlowHub Python SDK

rsflowhub is the official PyPI package for RSFlowHub. Install it with pip install rsflowhub, set RSFLOWHUB_API_KEY and call any API as client.ai.slug_in_snake_case(...). It supports Python 3.9+, has a sync RSFlowHub and an async AsyncRSFlowHub client built on httpx, typed method stubs for mypy and Pyright, typed errors by error code and automatic retries for 429 and 5xx answers. New APIs work without updating the package.

Packagersflowhub on PyPI
Installpip install rsflowhub
RequiresPython 3.9 or newer, httpx
Works withDjango, FastAPI, Flask, Celery, scripts and notebooks
Sourcegithub.com/RSFlowHub/rsflowhub-python (MIT license)

Install

terminal Bash
pip install rsflowhub
# poetry add rsflowhub · uv add rsflowhub

Create an API key in your dashboard and put it in your environment. The SDK reads RSFLOWHUB_API_KEY automatically, or you can pass api_key=.

terminal Bash
export RSFLOWHUB_API_KEY=rfh_your_api_key

Make your first call

sentiment.py Python
from rsflowhub import RSFlowHub

client = RSFlowHub()  # reads RSFLOWHUB_API_KEY, or RSFlowHub(api_key="rfh_...")

res = client.ai.sentiment_analysis(
    text="Setup took two minutes and support answered right away.",
)

print(res.result["sentiment"])  # "positive"
print(res.result)               # the whole AI output
print(res.request_id)           # "req_..." quote it when you contact support

Async client

AsyncRSFlowHub has exactly the same methods; each returns an awaitable. Use it in FastAPI, aiohttp, Django async views or anywhere you run several calls at once.

async_example.py Python
import asyncio
from rsflowhub import AsyncRSFlowHub


async def main() -> None:
    async with AsyncRSFlowHub() as client:
        # run several calls at the same time
        sentiment, summary = await asyncio.gather(
            client.ai.sentiment_analysis(text=review),
            client.ai.text_summarize(text=review, length="short"),
        )
        print(sentiment.result["sentiment"], summary.result)


asyncio.run(main())

The response object

Every successful call returns a read-only rsflowhub.Response built from the API envelope {success, request_id, data, meta}. AI endpoints put their output in data.result.

UseWhat you get
res.resultThe AI output (data.result), or data when there is no result (knowledge bases, chatbots)
res.data, res["key"], dict(res)Anything under data (the response is a read-only mapping)
res.get_path("result.aspects.0.name", default)One value, with dot notation
res.request_id, res.metaServer request id and {version, timestamp}
res.status_code, res.headersHTTP status and headers
res.rate_limit{"limit", "remaining", "reset"} from the X-RateLimit-* headers

Calling any API

Methods are not hard-coded. The method is the endpoint's slug in snake_case, grouped by resource: client.ai, client.knowledge_bases, client.chatbots, client.faq_collections and client.account. See every endpoint in the API reference.

calling.py Python
# The method name is the endpoint slug in snake_case (camelCase also works)
client.ai.translation(text="Hello", target_language="French")
client.ai.pii_redaction(text="Call me on 555-0100")
client.ai.ticket_analyze(ticket="My order never arrived")

# The body can also be one dict
client.ai.chat({"message": "Hi!"})

# An AI API released after you installed the SDK works the same way
client.ai.brand_new_endpoint(text="...")
client.call("ai", "brand_new_endpoint", text="...")

# A resource the SDK does not know yet
client.resource("webhooks").list()

# Any route: method, path, body, query
usage = client.request("GET", "/account/usage", query={"page": 2})

Path ids and file uploads

ids_and_files.py Python
from pathlib import Path

# Ids in the URL come first, then the body
client.knowledge_bases.ask(12, question="Refund policy?")
client.chatbots.get_conversation(3, "conv_abc123")

# ...or by name
client.knowledge_bases.ask(id=12, question="Refund policy?")

# A pathlib.Path, bytes or an open binary file makes it a file upload
client.knowledge_bases.create_document(
    12,
    file=Path("refund-policy.pdf"),
    metadata={"source": "help-center"},  # sent as metadata[source]
)

Knowledge bases (RAG) and chatbots

Build a searchable help center from your documents and FAQs, then answer questions from it or run a chatbot on top of it.

help_center.py Python
from pathlib import Path

# 1. A knowledge base for your help center
kb = client.knowledge_bases.create(name="Help center")
kb_id = kb.get_path("knowledge_base.id")

# 2. Add content: a document, or a single FAQ item
client.knowledge_bases.create_document(kb_id, file=Path("refund-policy.pdf"))
client.knowledge_bases.create_item(
    kb_id,
    content="How long do refunds take?",
    answer="Refunds reach your card in 5 to 7 business days.",
)

# 3. Ask questions grounded in that content
answer = client.knowledge_bases.ask(kb_id, question="When will I get my money back?")
print(answer.result)

# A chatbot (created in the dashboard or with client.chatbots.create(...))
reply = client.chatbots.send_message(chatbot_id, message="Where is my order?")
conversation_id = reply["conversation_id"]

Errors

Every API error is raised as an rsflowhub.APIError subclass chosen by the error code in the error envelope, with status_code, code, message, details and request_id. Everything extends rsflowhub.RSFlowHubError.

errors.py Python
import rsflowhub

try:
    client.ai.text_summarize(text=article)
except rsflowhub.ValidationError as e:
    print(e.errors)                       # {"text": ["The text field is required."]}
except rsflowhub.InsufficientCreditsError as e:
    print(e.required_credits, e.available_credits)
except rsflowhub.RateLimitError as e:
    print(e.retry_after)                  # already retried max_retries times
except rsflowhub.APIError as e:
    print(e.status_code, e.code, e.message, e.request_id)
except rsflowhub.APIConnectionError:
    print("network problem or timeout")   # APITimeoutError is a subclass
ExceptionStatusError codesExtra
AuthenticationError401API_KEY_MISSING, INVALID_API_KEY
InsufficientCreditsError402INSUFFICIENT_CREDITSrequired_credits, available_credits
PermissionDeniedError403SPENDING_LIMIT_REACHED, USER_INACTIVE
NotFoundError404ENDPOINT_NOT_FOUND
ValidationError422VALIDATION_ERRORerrors
RateLimitError429RATE_LIMIT_EXCEEDEDretry_after
InternalServerError500INTERNAL_SERVER_ERROR
ServiceUnavailableError502 / 503AI_PROVIDER_ERROR, PROVIDER_UNAVAILABLE
APIConnectionError / APITimeoutErrornoneNetwork failure / too slow

Options, retries and timeouts

429, 502, 503, 504 and network failures are retried twice with backoff, respecting Retry-After; those answers are never charged. Other errors are raised at once. Limits and the credit formula are on Rate limits & credits. Create one client and reuse it; it is safe to share across threads.

options.py Python
client = RSFlowHub(
    api_key="rfh_...",                       # default: RSFLOWHUB_API_KEY
    base_url="https://rsflowhub.com/api/v1", # default: RSFLOWHUB_BASE_URL
    timeout=60.0,                            # seconds per attempt
    max_retries=2,                           # for 429, 502, 503, 504 and network errors
    default_headers={},                      # extra headers on every request
    http_client=None,                        # your own httpx.Client (proxies, event hooks, tests)
    live_spec=True,                          # look up unknown non-AI methods in the OpenAPI document
)

# Per call
client.ai.chat(message="Hi", timeout=10, max_retries=0, extra_headers={"X-Trace": "abc"})

res.rate_limit   # {"limit": 60, "remaining": 59, "reset": None}

FastAPI, Django, Flask and Celery

main.py
from contextlib import asynccontextmanager

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

import rsflowhub
from rsflowhub import AsyncRSFlowHub

client = AsyncRSFlowHub()


@asynccontextmanager
async def lifespan(app: FastAPI):
    yield
    await client.aclose()


app = FastAPI(lifespan=lifespan)


class Comment(BaseModel):
    text: str


@app.post("/moderate")
async def moderate(comment: Comment):
    try:
        res = await client.ai.comment_moderate(comment=comment.text)
    except rsflowhub.ValidationError as e:
        raise HTTPException(422, detail=e.errors)
    except rsflowhub.APIError as e:
        raise HTTPException(e.status_code, detail=e.message)
    return res.result
# views.py  (settings.py: RSFLOWHUB_API_KEY = env("RSFLOWHUB_API_KEY"))
import json

from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.http import require_POST

import rsflowhub
from rsflowhub import RSFlowHub

client = RSFlowHub(api_key=settings.RSFLOWHUB_API_KEY)  # once, reused by every request


@require_POST
def ask_help_center(request):
    question = json.loads(request.body)["question"]
    try:
        res = client.knowledge_bases.ask(settings.HELP_CENTER_KB_ID, question=question)
    except rsflowhub.APIError as e:
        return JsonResponse({"error": e.message}, status=e.status_code)
    return JsonResponse(res.data)
from flask import Flask, jsonify, request

import rsflowhub
from rsflowhub import RSFlowHub

app = Flask(__name__)
client = RSFlowHub()


@app.post("/summarize")
def summarize():
    try:
        res = client.ai.text_summarize(text=request.json["text"], format="bullet_points")
    except rsflowhub.APIError as e:
        return jsonify(error=e.message, code=e.code), e.status_code
    return jsonify(res.result)
# tasks.py: long or bulk work belongs in a background task
from celery import shared_task

import rsflowhub
from rsflowhub import RSFlowHub

client = RSFlowHub()


# Retry only errors that are never charged (network, AI temporarily down)
@shared_task(
    autoretry_for=(rsflowhub.APIConnectionError, rsflowhub.ServiceUnavailableError),
    retry_backoff=True,
    max_retries=3,
)
def triage_ticket(ticket_id: int) -> None:
    ticket = Ticket.objects.get(pk=ticket_id)
    analysis = client.ai.ticket_analyze(ticket=ticket.body).result
    ticket.priority = analysis["priority"]
    ticket.department = analysis["suggested_department"]
    ticket.save(update_fields=["priority", "department"])

Type hints and staying up to date

  • New AI APIs work at once: they are called by name, no upgrade needed.
  • Other new routes are looked up in the public OpenAPI document the first time you call them.
  • Type hints: the package ships typed stubs (py.typed) with every method's keyword arguments and Literal choices, so mypy, Pyright and your editor catch mistakes early. They are regenerated weekly; pip install -U rsflowhub picks them up.
  • The full method list is in docs/ENDPOINTS.md.

Python SDK Questions

Run pip install rsflowhub (or poetry add / uv add rsflowhub), set RSFLOWHUB_API_KEY and create a client with RSFlowHub(). It supports Python 3.9 and newer and depends only on httpx.

Yes. AsyncRSFlowHub has the same methods as RSFlowHub, and each one returns an awaitable: res = await client.ai.sentiment_analysis(text=...). Create one client when your app starts and reuse it; close it with await client.aclose() or async with.

No. AI endpoints are called by name in snake_case, for example client.ai.new_endpoint_name(...), so new APIs work immediately. Other new routes are looked up in the public OpenAPI document the first time you call them. Updating only adds type hints for the new methods.

Yes. The package ships typed stubs generated from the OpenAPI document: every method has typed keyword arguments, with Literal choices for fixed values, so mypy, Pyright and your editor catch a missing or wrong argument before you run the code.

Pass a pathlib.Path, bytes or an open binary file as file: client.knowledge_bases.create_document(kb_id, file=Path("policy.pdf")). The SDK sends it as multipart/form-data.

Ready to build?

Create your free account and make your first API call in minutes.

RSFlowHub

Sign in to continue

You'll come straight back to this page.

Forgot password?

New to RSFlowHub? Create a free account