com um clique
openrag-sdk
// Guide developers through integrating the OpenRAG SDK into applications with code examples, configuration, and best practices
// Guide developers through integrating the OpenRAG SDK into applications with code examples, configuration, and best practices
| name | openrag_sdk |
| description | Guide developers through integrating the OpenRAG SDK into applications with code examples, configuration, and best practices |
When the user asks to integrate the OpenRAG SDK or use OpenRAG in their application, follow this workflow.
Before starting SDK integration:
http://localhost:3000, https://api.example.com)curl <base_url> or curl <base_url>/healthPackage: openrag-sdk
Installation:
pip install openrag-sdk
Or with uv:
uv add openrag-sdk
Package: openrag-sdk
Installation:
npm install openrag-sdk
Or with other package managers:
yarn add openrag-sdk
pnpm add openrag-sdk
bun add openrag-sdk
Package: openrag-mcp
For MCP integration (Model Context Protocol):
pip install openrag-mcp
Or with uvx:
uvx openrag-mcp
The SDK can be configured via environment variables or constructor arguments:
Environment Variables:
OPENRAG_API_KEY=your-api-key # Required if authentication is enabled
OPENRAG_URL=http://localhost:3000 # Optional, defaults to localhost:3000
Constructor Arguments:
from openrag_sdk import OpenRAGClient
# Using environment variables (auto-discovers OPENRAG_API_KEY and OPENRAG_URL)
client = OpenRAGClient()
# Using explicit arguments
client = OpenRAGClient(
api_key="orag_...",
base_url="https://api.example.com"
)
Similar configuration options for TypeScript:
import { OpenRAGClient } from 'openrag-sdk';
// Using environment variables
const client = new OpenRAGClient();
// Using explicit configuration
const client = new OpenRAGClient({
apiKey: 'orag_...',
baseUrl: 'https://api.example.com'
});
Python:
import asyncio
from openrag_sdk import OpenRAGClient
async def main():
# Client auto-discovers OPENRAG_API_KEY and OPENRAG_URL from environment
async with OpenRAGClient() as client:
# Simple chat
response = await client.chat.create(message="What is RAG?")
print(response.response)
print(f"Chat ID: {response.chat_id}")
# Continue conversation
followup = await client.chat.create(
message="Tell me more",
chat_id=response.chat_id
)
print(followup.response)
asyncio.run(main())
TypeScript:
import { OpenRAGClient } from 'openrag-sdk';
async function main() {
const client = new OpenRAGClient();
// Simple chat
const response = await client.chat.create({
message: "What is RAG?"
});
console.log(response.response);
console.log(`Chat ID: ${response.chatId}`);
// Continue conversation
const followup = await client.chat.create({
message: "Tell me more",
chatId: response.chatId
});
console.log(followup.response);
}
main();
Python:
async def streaming_chat():
chat_id = None
async with OpenRAGClient() as client:
# Stream responses
async for event in await client.chat.create(
message="Explain RAG",
stream=True
):
if event.type == "content":
print(event.delta, end="", flush=True)
elif event.type == "sources":
for source in event.sources:
print(f"\nSource: {source.filename}")
elif event.type == "done":
chat_id = event.chat_id
asyncio.run(streaming_chat())
Python with stream() context manager:
async def streaming_with_context():
async with OpenRAGClient() as client:
# Full event iteration
async with client.chat.stream(message="Explain RAG") as stream:
async for event in stream:
if event.type == "content":
print(event.delta, end="", flush=True)
# Access aggregated data after iteration
print(f"\nChat ID: {stream.chat_id}")
# Get final text directly
async with client.chat.stream(message="Explain RAG") as stream:
text = await stream.final_text()
print(text)
asyncio.run(streaming_with_context())
TypeScript:
async function streamingChat() {
const client = new OpenRAGClient();
const stream = await client.chat.create({
message: "Explain RAG",
stream: true
});
for await (const event of stream) {
if (event.type === 'content') {
process.stdout.write(event.delta);
} else if (event.type === 'sources') {
for (const source of event.sources) {
console.log(`\nSource: ${source.filename}`);
}
} else if (event.type === 'done') {
console.log(`\nChat ID: ${event.chatId}`);
}
}
}
Python:
async def manage_conversations():
async with OpenRAGClient() as client:
# List all conversations
conversations = await client.chat.list()
for conv in conversations.conversations:
print(f"{conv.chat_id}: {conv.title}")
if not conversations.conversations:
print("No conversations found")
return
chat_id = conversations.conversations[0].chat_id
# Get specific conversation with messages
conversation = await client.chat.get(chat_id)
for msg in conversation.messages:
print(f"{msg.role}: {msg.content}")
# Delete conversation
await client.chat.delete(chat_id)
asyncio.run(manage_conversations())
TypeScript:
async function manageConversations() {
const client = new OpenRAGClient();
// List all conversations
const conversations = await client.chat.list();
for (const conv of conversations.conversations) {
console.log(`${conv.chatId}: ${conv.title}`);
}
if (!conversations.conversations.length) {
console.log("No conversations found");
return;
}
const chatId = conversations.conversations[0].chatId;
// Get specific conversation
const conversation = await client.chat.get(chatId);
for (const msg of conversation.messages) {
console.log(`${msg.role}: ${msg.content}`);
}
// Delete conversation
await client.chat.delete(chatId);
}
Python:
async def search_knowledge():
async with OpenRAGClient() as client:
# Basic search
results = await client.search.query("document processing")
for result in results.results:
print(f"{result.filename} (score: {result.score})")
print(f"{result.text[:100]}...")
# Search with filters
from openrag_sdk import SearchFilters
results = await client.search.query(
"API documentation",
filters=SearchFilters(
data_sources=["api-docs.pdf"],
document_types=["application/pdf"]
),
limit=5,
score_threshold=0.5
)
asyncio.run(search_knowledge())
TypeScript:
async function searchKnowledge() {
const client = new OpenRAGClient();
// Basic search
const results = await client.search.query("document processing");
for (const result of results.results) {
console.log(`${result.filename} (score: ${result.score})`);
console.log(`${result.text.substring(0, 100)}...`);
}
// Search with filters
const filtered = await client.search.query("API documentation", {
filters: {
data_sources: ["api-docs.pdf"],
document_types: ["application/pdf"]
},
limit: 5,
scoreThreshold: 0.5
});
}
Python:
async def manage_documents():
async with OpenRAGClient() as client:
# Ingest a file (waits for completion by default)
result = await client.documents.ingest(file_path="./report.pdf")
print(f"Status: {result.status}")
# Ingest from file object
with open("./report.pdf", "rb") as f:
result = await client.documents.ingest(file=f, filename="report.pdf")
# Poll for completion manually
final_status = await client.documents.wait_for_task(result.task_id)
print(f"Status: {final_status.status}")
print(f"Successful files: {final_status.successful_files}")
# Delete a document
result = await client.documents.delete("report.pdf")
print(f"Success: {result.success}")
asyncio.run(manage_documents())
TypeScript:
async function manageDocuments() {
const client = new OpenRAGClient();
// Ingest a file
const result = await client.documents.ingest({
filePath: "./report.pdf"
});
console.log(`Status: ${result.status}`);
// Poll for completion
const finalStatus = await client.documents.waitForTask(result.task_id);
console.log(`Status: ${finalStatus.status}`);
console.log(`Successful files: ${finalStatus.successful_files}`);
// Delete a document
const deleteResult = await client.documents.delete("report.pdf");
console.log(`Success: ${deleteResult.success}`);
}
Python:
async def manage_settings():
async with OpenRAGClient() as client:
# Get settings
settings = await client.settings.get()
print(f"LLM Provider: {settings.agent.llm_provider}")
print(f"LLM Model: {settings.agent.llm_model}")
print(f"Embedding Model: {settings.knowledge.embedding_model}")
# Update settings
await client.settings.update({
"llm_provider": "openai",
"llm_model": "gpt-4o",
"embedding_provider": "openai",
"embedding_model": "text-embedding-3-small"
})
asyncio.run(manage_settings())
TypeScript:
async function manageSettings() {
const client = new OpenRAGClient();
// Get settings
const settings = await client.settings.get();
console.log(`LLM Provider: ${settings.agent.llmProvider}`);
console.log(`LLM Model: ${settings.agent.llmModel}`);
// Update settings
await client.settings.update({
llm_provider: "openai",
llm_model: "gpt-4o",
embedding_provider: "openai",
embedding_model: "text-embedding-3-small"
});
}
Python:
async def use_knowledge_filters():
async with OpenRAGClient() as client:
# Create a knowledge filter
result = await client.knowledge_filters.create({
"name": "Technical Docs",
"description": "Filter for technical documentation",
"queryData": {
"query": "technical",
"filters": {
"document_types": ["application/pdf"]
},
"limit": 10,
"scoreThreshold": 0.5
}
})
filter_id = result.id
# Search for filters
filters = await client.knowledge_filters.search("Technical")
for f in filters:
print(f"{f.name}: {f.description}")
# Update a filter
await client.knowledge_filters.update(filter_id, {
"description": "Updated description"
})
# Delete a filter
await client.knowledge_filters.delete(filter_id)
# Use filter in chat
response = await client.chat.create(
message="Explain the API",
filter_id=filter_id
)
# Use filter in search
results = await client.search.query(
"API endpoints",
filter_id=filter_id
)
asyncio.run(use_knowledge_filters())
TypeScript:
async function useKnowledgeFilters() {
const client = new OpenRAGClient();
// Create a knowledge filter
const result = await client.knowledgeFilters.create({
name: "Technical Docs",
description: "Filter for technical documentation",
queryData: {
query: "technical",
filters: {
documentTypes: ["application/pdf"]
},
limit: 10,
scoreThreshold: 0.5
}
});
const filterId = result.id;
// Use filter in chat
const response = await client.chat.create({
message: "Explain the API",
filterId: filterId
});
// Use filter in search
const results = await client.search.query({
query: "API endpoints",
filterId: filterId
});
}
from openrag_sdk import (
OpenRAGError,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError
)
async def handle_errors():
try:
async with OpenRAGClient() as client:
response = await client.chat.create(message="Hello")
except AuthenticationError as e:
print(f"Invalid API key: {e.message}")
except NotFoundError as e:
print(f"Resource not found: {e.message}")
except ValidationError as e:
print(f"Invalid request: {e.message}")
except RateLimitError as e:
print(f"Rate limited: {e.message}")
except ServerError as e:
print(f"Server error: {e.message} (status: {e.status_code})")
except OpenRAGError as e:
print(f"API error: {e.message} (status: {e.status_code})")
import {
OpenRAGClient,
OpenRAGError,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError
} from 'openrag-sdk';
async function handleErrors() {
try {
const client = new OpenRAGClient();
const response = await client.chat.create({ message: "Hello" });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error(`Invalid API key: ${error.message}`);
} else if (error instanceof NotFoundError) {
console.error(`Resource not found: ${error.message}`);
} else if (error instanceof ValidationError) {
console.error(`Invalid request: ${error.message}`);
} else if (error instanceof RateLimitError) {
console.error(`Rate limited: ${error.message}`);
} else if (error instanceof ServerError) {
console.error(`Server error: ${error.message}`);
} else if (error instanceof OpenRAGError) {
console.error(`API error: ${error.message}`);
}
}
}
from fastapi import FastAPI, HTTPException
from openrag_sdk import OpenRAGClient
from pydantic import BaseModel
app = FastAPI()
client = OpenRAGClient()
class ChatRequest(BaseModel):
message: str
chat_id: str | None = None
@app.post("/api/chat")
async def chat(request: ChatRequest):
try:
response = await client.chat.create(
message=request.message,
chat_id=request.chat_id
)
return {
"answer": response.response,
"sources": [{"filename": s.filename, "score": s.score} for s in response.sources],
"chat_id": response.chat_id
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/api/search")
async def search(query: str, limit: int = 10):
try:
results = await client.search.query(query, limit=limit)
return {
"results": [
{
"filename": r.filename,
"text": r.text,
"score": r.score
}
for r in results.results
]
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
import express from 'express';
import { OpenRAGClient } from 'openrag-sdk';
const app = express();
const client = new OpenRAGClient();
app.use(express.json());
app.post('/api/chat', async (req, res) => {
try {
const { message, chatId } = req.body;
const response = await client.chat.create({
message,
chatId
});
res.json({
answer: response.response,
sources: response.sources.map(s => ({
filename: s.filename,
score: s.score
})),
chatId: response.chatId
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/api/search', async (req, res) => {
try {
const { query, limit = 10 } = req.query;
const results = await client.search.query({
query: query as string,
limit: Number(limit)
});
res.json({
results: results.results.map(r => ({
filename: r.filename,
text: r.text,
score: r.score
}))
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3001, () => {
console.log('Server running on port 3001');
});
import { useState } from 'react';
import { OpenRAGClient } from 'openrag-sdk';
// Note: In production, proxy API calls through your backend
// to avoid exposing API keys in the browser
const client = new OpenRAGClient({
baseUrl: process.env.REACT_APP_OPENRAG_URL
});
function ChatComponent() {
const [message, setMessage] = useState('');
const [chatId, setChatId] = useState<string | null>(null);
const [response, setResponse] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const result = await client.chat.create({
message,
chatId,
limit: 5
});
setResponse(result.response);
setChatId(result.chatId);
setMessage('');
} catch (error) {
console.error('Chat error:', error);
} finally {
setLoading(false);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Ask a question..."
disabled={loading}
/>
<button type="submit" disabled={loading}>
{loading ? 'Sending...' : 'Send'}
</button>
</form>
{response && (
<div className="response">
{response}
</div>
)}
</div>
);
}
import { useState } from 'react';
import { OpenRAGClient } from 'openrag-sdk';
function StreamingChat() {
const [message, setMessage] = useState('');
const [response, setResponse] = useState('');
const [streaming, setStreaming] = useState(false);
const client = new OpenRAGClient();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setStreaming(true);
setResponse('');
try {
const stream = await client.chat.create({
message,
stream: true
});
for await (const event of stream) {
if (event.type === 'content') {
setResponse(prev => prev + event.delta);
}
}
} catch (error) {
console.error('Streaming error:', error);
} finally {
setStreaming(false);
setMessage('');
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
disabled={streaming}
/>
<button type="submit" disabled={streaming}>
{streaming ? 'Streaming...' : 'Send'}
</button>
</form>
<div className="response">
{response}
{streaming && <span className="cursor">▊</span>}
</div>
</div>
);
}
Never expose API keys in client-side code
Use HTTPS in production
Validate and sanitize inputs
Implement proper error handling
Follow OWASP guidelines
import pytest
from openrag_sdk import OpenRAGClient
@pytest.fixture
async def client():
async with OpenRAGClient() as client:
yield client
@pytest.mark.asyncio
async def test_chat_basic(client):
response = await client.chat.create(message="Hello")
assert response.response is not None
assert isinstance(response.sources, list)
assert response.chat_id is not None
@pytest.mark.asyncio
async def test_search_with_filters(client):
results = await client.search.query(
"test",
filters={"document_types": ["application/pdf"]}
)
assert isinstance(results.results, list)
import { describe, it, expect } from 'vitest';
import { OpenRAGClient } from 'openrag-sdk';
describe('OpenRAG SDK', () => {
const client = new OpenRAGClient();
it('should chat successfully', async () => {
const response = await client.chat.create({
message: 'Hello'
});
expect(response.response).toBeDefined();
expect(response.sources).toBeInstanceOf(Array);
expect(response.chatId).toBeDefined();
});
it('should search with filters', async () => {
const results = await client.search.query({
query: 'test',
filters: {
documentTypes: ['application/pdf']
}
});
expect(results.results).toBeInstanceOf(Array);
});
});
http://localhost:3000 or https://api.example.com)curl <base_url> or curl <base_url>/healthlimit values (don't retrieve more sources than needed)score_threshold to filter low-quality resultsscore_threshold to filter irrelevant resultsEnvironment configuration
Health checks
Monitoring and logging
Fallback handling
Scaling
After integration, document:
Before considering integration complete: