Open WebUI Python Client: Install, Authenticate, and Integrate
Complete guide to Open WebUI Python SDK. Install openwebui-client or owui-client, authenticate with API keys, and build chat completions, file uploads, and async workflows.
- Open WebUI offers three Python SDK options: owui-client (full-featured, async), openwebui-client (simple, OpenAI-compatible), and the OpenAI SDK (inference only).
- Install with pip, generate an API key in the UI, and authenticate by passing the key to your client.
- Common operations include listing models, creating chat completions, and uploading files to knowledge bases.
- Use async/await patterns with owui-client for production systems handling many parallel requests.
- Deploy Python scripts anywhere that can reach your Open WebUI instance over HTTPS, including Opsily-managed hosting.
The Open WebUI Python client lets you programmatically interact with your self-hosted AI instance through code. You can create chat completions, list available models, upload documents, and manage knowledge bases--all from Python. This guide shows you how to install the SDK, authenticate, and build production-ready integrations.
What Python Clients Are Available for Open WebUI?
Open WebUI does not have a single official Python client. Instead, you have three options, each suited to different use cases. Understanding the tradeoffs matters because picking the wrong one wastes time.
The first option is owui-client, a community-built client announced in December 2025. It provides 100% endpoint coverage of the Open WebUI API with full type hints and native async support. This is the most feature-complete option and the one you should reach for if you are building production integrations that need async concurrency, error recovery, and access to every API endpoint. The GitHub discussion where it was announced shows the full scope of what it covers--auth, system endpoints, content management, and inference. If you need async/await patterns or plan to scale beyond a few hundred requests per second, pick this one.
The second option is openwebui-client, available on PyPI as version 0.3.2 (released July 29, 2025). This client requires Python 3.10 or higher and uses an OpenAI-compatible interface with Open WebUI extensions. It is lighter weight than owui-client and works well for basic operations: chat completions, model listing, and simple chat management. Many Python developers are already familiar with the OpenAI SDK, so this library feels natural. Use this if you want something simple, well-documented, and happy to trade full API coverage for ease of use.
The third option is the OpenAI Python SDK itself. Because Open WebUI exposes an OpenAI-compatible API endpoint, you can use the standard openai package to query completions and chat endpoints directly. This works but locks you out of Open WebUI-specific features like file uploads, knowledge base management, and user/workspace controls. Reserve this for read-only inference workloads where you only care about talking to an LLM model and do not need Open WebUI's feature set.
Use owui-client for production systems and async work. Use openwebui-client for simple CRUD operations and when you want a smaller dependency footprint. Use the OpenAI SDK only if you are migrating existing OpenAI code and want minimal changes.
How Do I Install and Configure the Python Client?
Start by creating a Python 3.10+ virtual environment. The official Open WebUI documentation recommends Python 3.11, so use that if you have it available.
python3.11 -m venv open_webui_env
source open_webui_env/bin/activate # On Windows: open_webui_env\Scripts\activate
If you prefer uv (a faster, Rust-based package manager), you can create an environment and install in one step:
uv venv open_webui_env
source open_webui_env/bin/activate
Now install the client. For openwebui-client (the simpler option):
pip install openwebui-client
For owui-client (the fully-featured option with async support), you need to install directly from GitHub since it is not yet on PyPI:
pip install git+https://github.com/open-webui/open-webui.git#subdirectory=backend
Alternatively, clone the repository and install locally:
git clone https://github.com/open-webui/open-webui.git
cd open-webui
pip install -e.
Verify the installation:
python -c "import openwebui_client; print(openwebui_client.__version__)"
Create a .env file in your project root to store your API key and Open WebUI base URL (more on this in the next section):
OPEN_WEBUI_BASE_URL=http://localhost:8000
OPEN_WEBUI_API_KEY=your-api-key-here
Load it in your Python scripts with python-dotenv:
pip install python-dotenv
How Do I Authenticate: Getting and Using API Keys?
Open WebUI authentication happens via API key. First, you need to generate one in the Open WebUI web interface. Log in to your Open WebUI instance, go to Settings (usually a gear icon in the bottom-left), then Account or API section. Create a new API key and copy it immediately--you will not see it again.
In your Python code, pass the API key as a Bearer token. With openwebui-client:
from openwebui_client import OpenWebUI
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("OPEN_WEBUI_API_KEY")
base_url = os.getenv("OPEN_WEBUI_BASE_URL", "http://localhost:8000")
client = OpenWebUI(api_key=api_key, base_url=base_url)
With owui-client:
from owui_client import Client
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("OPEN_WEBUI_API_KEY")
base_url = os.getenv("OPEN_WEBUI_BASE_URL", "http://localhost:8000")
client = Client(base_url=base_url, headers={"Authorization": f"Bearer {api_key}"})
Never hardcode API keys in your code. Use environment variables. If you are running Python scripts on a server--for example, on Opsily's managed Open WebUI hosting--store the key in your deployment configuration (secrets, environment variables, or a mounted secret file) and load it at runtime.
Rotate your API keys periodically, especially if you suspect compromise. Most Open WebUI instances let you revoke old keys in the same Settings panel without affecting active sessions.
How Do I Perform Basic Operations?
Listing available models is often the first thing you want to check. Here is how with openwebui-client:
models = client.get_models()
for model in models:
print(f"Model: {model.name} (ID: {model.id})")
Creating a chat completion is straightforward:
response = client.chat_completions(
model="llama2",
messages=[
{"role": "user", "content": "What is Open WebUI?"}
],
stream=False
)
print(response.choices[0].message.content)
If you want streaming responses (word-by-word output), set stream=True:
response = client.chat_completions(
model="llama2",
messages=[
{"role": "user", "content": "Explain the capital of France."}
],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
Creating a chat conversation (not just a one-off completion) requires a few more steps:
# Create a new chat
chat = client.create_chat(title="My First Chat")
chat_id = chat.id
# Add messages to the chat
message = client.chat_message(
chat_id=chat_id,
model="llama2",
content="Hello, assistant. What can you do?"
)
print(message.content) # The assistant's response
To list all your chats:
chats = client.get_chats()
for chat in chats:
print(f"Chat: {chat.title} (ID: {chat.id})")
How Do I Upload Files and Manage Knowledge Bases?
Open WebUI supports uploading documents and organizing them into knowledge bases. This is useful if you want to feed your LLM context from your own files--a technique called Retrieval-Augmented Generation (RAG).
File upload with openwebui-client:
import os
with open("document.pdf", "rb") as f:
upload_response = client.upload_file(
file=f,
filename="document.pdf"
)
file_id = upload_response.id
print(f"Uploaded file ID: {file_id}")
Knowledge bases group files into collections you can reference during chat. Create one:
kb_response = client.create_knowledge_base(
name="My Documents",
description="A collection of my important files"
)
kb_id = kb_response.id
Add the uploaded file to the knowledge base:
client.add_file_to_kb(
kb_id=kb_id,
file_id=file_id
)
When you query the LLM, reference the knowledge base to give it context:
response = client.chat_completions(
model="llama2",
messages=[
{"role": "user", "content": "Summarize the document I uploaded."}
],
knowledge_base_id=kb_id
)
For bulk document ingestion, Open WebUI provides an oikb (Open WebUI Knowledge Base) command-line tool. This is useful if you have hundreds of files to index:
oikb sync --kb-name "My Documents" --source-dir./documents
This tool watches a directory and automatically indexes new files as they arrive. Check the official docs or GitHub for the latest usage.
How Do I Build Async Patterns for Production?
If you are processing many requests in parallel, synchronous code will be slow. owui-client supports async/await, letting you issue hundreds of requests concurrently without blocking.
import asyncio
from owui_client import AsyncClient
async def main():
client = AsyncClient(base_url="http://localhost:8000", headers={"Authorization": f"Bearer {api_key}"})
# Fetch multiple models in parallel
tasks = [
client.models.list(),
client.models.list(),
client.models.list()
]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
For chat completions:
async def chat_parallel():
client = AsyncClient(...)
messages_to_send = [
"What is Python?",
"What is JavaScript?",
"What is Rust?"
]
tasks = [
client.chat.completions.create(
model="llama2",
messages=[{"role": "user", "content": msg}]
)
for msg in messages_to_send
]
responses = await asyncio.gather(*tasks)
for resp in responses:
print(resp.choices[0].message.content)
asyncio.run(chat_parallel())
Error handling is critical. Wrap requests in try/except and implement exponential backoff for transient failures:
import asyncio
from owui_client import AsyncClient
from openwebui_client.exceptions import APIError
async def resilient_request(client, model, messages, max_retries=3):
for attempt in range(max_retries):
try:
response = await client.chat.completions.create(
model=model,
messages=messages
)
return response
except APIError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # 1s, 2s, 4s
print(f"Request failed. Retrying in {wait_time}s...")
await asyncio.sleep(wait_time)
else:
raise
For rate limiting, track your requests and throttle if needed:
import time
class RateLimitedClient:
def __init__(self, client, requests_per_second=5):
self.client = client
self.rate_limit = requests_per_second
self.last_request_time = 0
async def request(self, *args, **kwargs):
elapsed = time.time() - self.last_request_time
min_interval = 1.0 / self.rate_limit
if elapsed < min_interval:
await asyncio.sleep(min_interval - elapsed)
self.last_request_time = time.time()
return await self.client.request(*args, **kwargs)
How Do I Deploy Python Scripts on Opsily-Hosted Open WebUI?
If you are running Open WebUI on Opsily's managed hosting, you get a dedicated instance with a public or private URL. Connection is the same as self-hosted: you need the base URL and an API key.
When Opsily provisions your instance, you will receive connection details. Use those in your environment variables:
OPEN_WEBUI_BASE_URL=https://your-instance.opsily.app # or your custom domain
OPEN_WEBUI_API_KEY=your-api-key
Your Python code runs anywhere--your laptop, a CI/CD pipeline, a server--as long as it can reach your Opsily instance over HTTPS. Most teams deploy Python scripts as:
- Scheduled jobs (cron or cloud schedulers) that run daily/weekly to sync documents or refresh caches
- API servers (Flask, FastAPI, Django) that accept requests and forward them to Open WebUI
- Standalone scripts for one-off tasks like bulk file imports
For an API server wrapper, here is a minimal FastAPI example:
from fastapi import FastAPI, HTTPException
from openwebui_client import OpenWebUI
import os
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
client = OpenWebUI(
api_key=os.getenv("OPEN_WEBUI_API_KEY"),
base_url=os.getenv("OPEN_WEBUI_BASE_URL")
)
@app.post("/ask")
async def ask(question: str):
try:
response = client.chat_completions(
model="llama2",
messages=[{"role": "user", "content": question}]
)
return {"answer": response.choices[0].message.content}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8001)
Deploy this on any cloud platform that supports Python (AWS Lambda, Google Cloud Functions, Heroku, Railway, etc.). Store your API key as a secret in your deployment platform so it does not leak into version control.
See Opsily's managed Open WebUI hosting page for team collaboration features and how to invite team members to your instance.
Frequently Asked Questions
What is the difference between owui-client and openwebui-client?
owui-client is a community library with 100% Open WebUI API coverage, full type hints, and native async support. It is ideal for production systems and async workloads. openwebui-client is simpler, uses an OpenAI-compatible interface, and requires less setup. Pick owui-client if you need async or full API coverage; pick openwebui-client if you want a lightweight, easy-to-learn SDK.
Can I use the OpenAI SDK with Open WebUI?
Yes, because Open WebUI exposes an OpenAI-compatible /v1/chat/completions endpoint. However, you will not be able to use Open WebUI-specific features like file uploads, knowledge bases, or workspace management. Use it only for inference if you are porting existing OpenAI code.
How do I authenticate with an API key?
Generate an API key in Open WebUI's Settings > Account section. Then pass it as a Bearer token in the Authorization header when creating a client. Both owui-client and openwebui-client handle this automatically if you provide the key at initialization.
How do I handle errors and retries?
Wrap your requests in try/except blocks and catch APIError (or the relevant exception from your client library). Implement exponential backoff: wait 1 second, then 2, then 4, etc., before retrying. Most transient errors (timeouts, temporary server issues) resolve after one or two retries.
What rate limits should I expect?
Rate limits depend on your Open WebUI instance and the underlying model. There is no hard global limit documented, but do not fire more than 10-20 requests per second at a single model without testing first. Use a rate limiter in your code to avoid hammering the server.
How do I upload files programmatically?
Use client.upload_file(file=open(...), filename="...") to upload a file, then add it to a knowledge base with client.add_file_to_kb(kb_id=..., file_id=...). For bulk uploads, use the oikb command-line tool to watch a directory and auto-index new files.
Should I use async or synchronous code?
Use async if you are processing more than a few requests per second or need to make many parallel queries. Async code is faster and more efficient. Use synchronous code if you are writing simple scripts with only one or two requests in sequence--the overhead of async is not worth it.
Where do I find the Open WebUI API documentation?
The official docs are at docs.openwebui.com. The Python client libraries document their own methods in their README files on GitHub. The GitHub discussion announcing owui-client also lists all supported endpoints.
The Bottom Line
The Open WebUI Python client gives you programmatic access to your self-hosted AI platform. Pick owui-client for production async work, openwebui-client for simple CRUD operations, or the OpenAI SDK if you only need inference and already know that API.
Installation takes minutes: create a virtual environment, pip install, generate an API key, and you are done. From there, you can list models, create chats, upload documents, and manage knowledge bases entirely from Python code.
For teams running Open WebUI on Opsily's managed hosting, see how the platform handles team collaboration and document sharing by visiting the free private AI hosting page.