Metadata-Version: 2.4
Name: fastoai
Version: 1.0.3
Summary: Start an API server as OpenAI's
Author-email: Tang Ziya <tcztzy@gmail.Com>
Requires-Python: >=3.13
Requires-Dist: aiosqlite>=0.21.0
Requires-Dist: anthropic>=0.45.2
Requires-Dist: asyncpg>=0.30.0
Requires-Dist: asyncstdlib>=3.13.0
Requires-Dist: bcrypt>=4.2.1
Requires-Dist: fastapi[standard]>=0.115.8
Requires-Dist: fsspec[full]>=2025.2.0
Requires-Dist: loguru>=0.7.3
Requires-Dist: openai>=1.61.1
Requires-Dist: pydantic-settings>=2.7.1
Requires-Dist: pydantic[email]>=2.10.6
Requires-Dist: ruff>=0.9.5
Requires-Dist: sqlalchemy[asyncio]>=2.0.38
Requires-Dist: sqlmodel>=0.0.22
Requires-Dist: tenacity>=9.0.0
Requires-Dist: typer>=0.15.1
Requires-Dist: uvicorn[standard]>=0.34.0
Requires-Dist: valkey[libvalkey]>=6.0.2
Description-Content-Type: text/markdown

# FastOAI (OpenAI-like API Server)

## Motivation

This project is a simple API server that can be used to serve language models.
It is designed to be simple to use and easy to deploy. It is built using
[FastAPI](https://fastapi.tiangolo.com/), [Pydantic](https://docs.pydantic.dev/)
and [openai-python](https://github.com/openai/openai-python).

## Quick Start

The following [example](./examples/main.py) shows a case to overriding the
original streaming response, we append `[ollama]` to every chunk content.


```python
from fastapi.responses import StreamingResponse
from fastoai import FastOAI
from fastoai.requests import CompletionCreateParams
from fastoai.routers import router
from openai import AsyncOpenAI

app = FastOAI()


@app.post("/chat/completions")
async def create_chat_completions(params: CompletionCreateParams):
    client = AsyncOpenAI(api_key="ollama", base_url="http://localhost:11434/v1")
    response = await client.chat.completions.create(**params.model_dump())
    if params.stream:

        async def _stream():
            async for chunk in response:
                for choice in chunk.choices:
                    choice.delta.content += " [ollama]"
                yield f"data: {chunk.model_dump_json()}\n\n"
            else:
                yield "data: [DONE]\n\n"

        return StreamingResponse(_stream())
    return response

# Order matters, you should firstly define your own entrypoint functions, then
# include the existing router in order to override the original process with
# yours
app.include_router(router)
```

And that's it! You can now run the server using `uvicorn`:

```bash
uvicorn examples.main:app --reload
```

## Architecture

```mermaid
graph TD
    client["`*openai client* (Python/Node.js/RESTful)`"]-->fastoai[FastOAI server]
    fastoai-->ChatCompletion[OpenAI Chat Completion API]
    fastoai-->openai[OpenAI API]
    fastoai-->others[Any other API]
```
