Skip to main content
Use Emby’s OpenAI-compatible API with FastAPI using the traditional pip package manager.

Prerequisites

  • Python 3.9+ installed
  • An Emby account with an API key

Installation

1

Create Project Directory

mkdir emby-fastapi && cd emby-fastapi
2

Create Virtual Environment

python -m venv venv
Activate the virtual environment:
source venv/bin/activate
3

Install Dependencies

pip install fastapi uvicorn openai python-dotenv
Save dependencies to a file:
pip freeze > requirements.txt
4

Set Environment Variables

Create a .env file:
EMBY_API_KEY=your-api-key-here
EMBY_BASE_URL=https://dev.emby.ai/v1

Create the Application

1

Create the Emby Client

# emby_client.py
import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

emby = OpenAI(
    api_key=os.getenv("EMBY_API_KEY"),
    base_url=os.getenv("EMBY_BASE_URL"),
)
2

Create the FastAPI App

# main.py
from fastapi import FastAPI, HTTPException
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from emby_client import emby

app = FastAPI(title="Emby FastAPI")

class ChatRequest(BaseModel):
    message: str
    model: str = "gpt-4o"

class ChatResponse(BaseModel):
    reply: str

@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
    try:
        completion = emby.chat.completions.create(
            model=request.model,
            messages=[{"role": "user", "content": request.message}],
        )
        return ChatResponse(reply=completion.choices[0].message.content)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/chat/stream")
async def chat_stream(request: ChatRequest):
    async def generate():
        stream = emby.chat.completions.create(
            model=request.model,
            messages=[{"role": "user", "content": request.message}],
            stream=True,
        )
        for chunk in stream:
            content = chunk.choices[0].delta.content
            if content:
                yield content

    return StreamingResponse(generate(), media_type="text/plain")

@app.get("/health")
async def health():
    return {"status": "healthy"}
3

Run the Server

uvicorn main:app --reload
Your API is now running at http://localhost:8000Test it with:
curl -X POST http://localhost:8000/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello!"}'

Project Structure

emby-fastapi/
├── .env
├── venv/
├── requirements.txt
├── emby_client.py
└── main.py

requirements.txt

Your requirements.txt should look like:
fastapi>=0.104.0
uvicorn>=0.24.0
openai>=1.0.0
python-dotenv>=1.0.0
Install from requirements:
pip install -r requirements.txt

Advanced: Async Client

For better performance with FastAPI’s async nature:
# emby_client.py
import os
from dotenv import load_dotenv
from openai import AsyncOpenAI

load_dotenv()

emby = AsyncOpenAI(
    api_key=os.getenv("EMBY_API_KEY"),
    base_url=os.getenv("EMBY_BASE_URL"),
)
# main.py (async version)
@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
    completion = await emby.chat.completions.create(
        model=request.model,
        messages=[{"role": "user", "content": request.message}],
    )
    return ChatResponse(reply=completion.choices[0].message.content)

Docker Deployment

Create a Dockerfile:
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Build and run:
docker build -t emby-fastapi .
docker run -p 8000:8000 --env-file .env emby-fastapi

Available Models

Use any Emby supported model:
# Popular choices
model = "gpt-4o"           # Fast and capable
model = "gpt-5"            # Most powerful
model = "claude-sonnet-4-5" # Anthropic's latest

Need Help?