Skip to main content

Official Python SDK for Reno AI API

Project description

Reno AI SDK

Official Python client for the Reno API. Simple, fast, and built with production use in mind.

Table of Contents


Installation

pip install renoai

Requires Python 3.8 or higher.

Quick Start

from renoai import Reno

client = Reno(api_key="reno_sk_xxx")

answer = client.ask("What is machine learning?")
print(answer)

Authentication

Every request requires an API key. You can pass it directly or load it from an environment variable (recommended for production):

import os
from renoai import Reno

client = Reno(api_key=os.environ["RENO_API_KEY"])

API keys follow the format reno_sk_.... Keep them secret and never commit them to version control.


Making Requests

ask()

The simplest way to get a response. Sends a single message and returns the reply as a plain string.

answer = client.ask("Explain quantum computing in simple terms.")
print(answer)

With an optional system prompt:

answer = client.ask(
    "What is the boiling point of water?",
    system="You are a science teacher. Keep answers under 2 sentences.",
    temperature=0.3,
    max_tokens=100,
)
print(answer)

Parameters

Parameter Type Default Description
prompt str required The user's question or instruction
system str None Optional system message
model str gemma2:2b-instruct Model to use
temperature float 0.7 Sampling temperature, 0 to 2
max_tokens int None Maximum tokens to generate

chat()

Full control over the conversation with a list of messages. Returns a Completion object.

response = client.chat([
    {"role": "system",    "content": "You are a helpful assistant."},
    {"role": "user",      "content": "What is Python?"},
    {"role": "assistant", "content": "Python is a high-level programming language."},
    {"role": "user",      "content": "What is it mainly used for?"},
])

print(response.text)
print(response.usage.total_tokens)

Parameters

Parameter Type Default Description
messages list required List of {"role": ..., "content": ...} dicts
model str gemma2:2b-instruct Model to use
temperature float 0.7 Sampling temperature, 0 to 2
max_tokens int None Maximum tokens to generate
stream bool False Enable streaming mode

Valid roles are user, assistant, and system.

Streaming

Stream tokens as they are generated instead of waiting for the full response.

Using stream_text() — yields plain strings, the easiest option:

for token in client.stream_text("Write me a short poem about the ocean."):
    print(token, end="", flush=True)
print()

Using chat() with stream=True — yields StreamChunk objects for full control:

chunks = client.chat(
    [{"role": "user", "content": "Tell me a story."}],
    stream=True,
)

full_text = ""
for chunk in chunks:
    if chunk.delta:
        full_text += chunk.delta
        print(chunk.delta, end="", flush=True)
    if chunk.is_final:
        print(f"\n\nFinished. Reason: {chunk.finish_reason}")

Conversations

Conversation manages message history automatically so you can focus on the dialogue.

from renoai import Reno, Conversation

client = Reno(api_key="reno_sk_xxx")
conv = Conversation(client, system="You are a friendly cooking assistant.")

print(conv.say("What should I make for dinner tonight?"))
print(conv.say("I only have chicken and rice."))
print(conv.say("How long will it take?"))

You can inspect or reset the history at any time:

# See the full message history
print(conv.history)

# Reset but keep the system prompt
conv.reset(keep_system=True)

# Reset everything
conv.reset(keep_system=False)

Models

Pass any supported model name via the model parameter:

response = client.chat(
    [{"role": "user", "content": "Hello!"}],
    model="gemma2:2b-instruct",
)

The default model is gemma2:2b-instruct.


Response Objects

Completion

Returned by chat() when not streaming.

response = client.chat([{"role": "user", "content": "Hi"}])

response.text          # the generated reply as a string
response.content       # alias for response.text
response.id            # unique response ID
response.model         # model that generated the response
response.choices       # list of Choice objects
response.usage         # token usage info

response.to_message()  # {"role": "assistant", "content": "..."} ready to append to history
response.to_dict()     # raw API response as a dict

Usage

response.usage.prompt_tokens      # tokens in your input
response.usage.completion_tokens  # tokens in the reply
response.usage.total_tokens       # total tokens consumed

StreamChunk

Yielded by streaming calls.

chunk.delta          # the new text in this chunk (str or None)
chunk.finish_reason  # "stop" on the last chunk, None otherwise
chunk.is_final       # True when this is the last chunk
chunk.to_dict()      # raw chunk data

Error Handling

The SDK raises typed exceptions so you can handle each failure case precisely.

from renoai import (
    RenoError,
    RenoConnectionError,
    RenoTimeoutError,
    RenoValidationError,
)
import time

try:
    answer = client.ask("Hello")

except RenoValidationError as e:
    # Bad input before the request was even sent
    print("Fix your input:", e.message)

except RenoConnectionError as e:
    # Could not reach the server at all
    print("Server unreachable:", e.message)

except RenoTimeoutError as e:
    # Request started but took too long
    print("Timed out:", e.message)

except RenoError as e:
    # Any other API-level error
    print(e.user_friendly())

    if e.is_retryable:
        wait = e.retry_after or 5
        print(f"Retrying in {wait}s...")
        time.sleep(wait)

Exception Hierarchy

RenoError                  # base class for all SDK exceptions
  RenoConnectionError      # network or DNS failure (code 6002)
  RenoTimeoutError         # request exceeded timeout (code 6003)
  RenoValidationError      # invalid input caught client-side (code 2001)

RenoError Properties

Property Type Description
code int Reno error code
message str Short description of the error
details str Extra context or suggestion from the server
is_retryable bool Whether it is safe to retry this request
retry_after float Seconds to wait before retrying (from Retry-After header)
user_friendly() str Formatted message with title, description, and tip

Production Loop Example

import time
from renoai import Reno, RenoError, RenoConnectionError, RenoTimeoutError, RenoValidationError

client = Reno(api_key="reno_sk_xxx")

while True:
    try:
        answer = client.ask("Summarize today's AI news.")
        print(answer)

    except RenoValidationError as e:
        print("Validation error:", e.message)
        break  # code bug, do not retry

    except RenoConnectionError:
        print("Connection failed, retrying in 10s...")
        time.sleep(10)
        continue

    except RenoTimeoutError:
        print("Timed out, retrying in 5s...")
        time.sleep(5)
        continue

    except RenoError as e:
        if e.is_retryable:
            wait = e.retry_after or 5
            print(f"Retryable error [{e.code}], waiting {wait}s...")
            time.sleep(wait)
            continue
        else:
            print(e.user_friendly())
            break  # auth, billing, content policy, etc.

    except KeyboardInterrupt:
        print("Stopped.")
        break

    time.sleep(3)

client.close()

Error Codes Reference

Range Category
1001 to 1008 Authentication and API key errors
2001 to 2009 Request validation errors
3001 to 3007 Model availability errors
4001 to 4005 Token and context length errors
5001 to 5006 Rate limiting and quota errors
6001 to 6006 Server and infrastructure errors
7001 to 7004 Content moderation errors
8001 to 8004 Billing and subscription errors
9001 to 9004 Internal and unexpected errors

Call error.user_friendly() on any RenoError to get a plain-English title, description, and actionable tip for any of these codes.


Configuration

Client Options

client = Reno(
    api_key="reno_sk_xxx",
    base_url="http://127.0.0.1:8000/api/v1",  # default
    timeout=30,                                  # seconds, default 30
    max_retries=3,                               # default 3
)

Context Manager

The client can be used as a context manager to ensure the HTTP session is always closed:

with Reno(api_key="reno_sk_xxx") as client:
    print(client.ask("Hello!"))

Running Tests

pip install pytest
pytest tests/ -v

To run a specific test file or test:

pytest tests/test_renoai.py -v
pytest tests/test_renoai.py::TestClientRequests::test_ask_success -v

License

MIT License. See LICENSE for details.

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

renoai-0.1.6.tar.gz (23.9 kB view details)

Uploaded Source

Built Distribution

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

renoai-0.1.6-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file renoai-0.1.6.tar.gz.

File metadata

  • Download URL: renoai-0.1.6.tar.gz
  • Upload date:
  • Size: 23.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for renoai-0.1.6.tar.gz
Algorithm Hash digest
SHA256 8077fc4a89fcb181d4297789b00ddf4daade36a96cdb55d564d1424c539eb695
MD5 ab682ee06dc9efaa39095dc1eef50b04
BLAKE2b-256 144576c3e10330ac975194aa98b92c2aca5dbb46bf63f8366218b43f1aea5e2d

See more details on using hashes here.

File details

Details for the file renoai-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: renoai-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for renoai-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 cf81f9a14118f2b01d1b87b7d5a01d0f19f91c1d6157f3d8f8604453e2e6c4bf
MD5 4f7c9ea66e8cdadbc075a60787153bcb
BLAKE2b-256 088e55d25098dc0c6c0c4fa3acfd42bda6f5212676bf63f9c5c00f89e1f65cc7

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