Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README for fastapi integration #912

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,57 @@ We recommend that you always instantiate a client (e.g., with `client = OpenAI()
- It's harder to mock for testing purposes
- It's not possible to control cleanup of network connections

## Integration Example

### FastAPI

```py
from openai import AsyncOpenAI
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI

class AioClient:
"""
async client with singleton approach
https://github.com/tiangolo/fastapi/discussions/8301
https://fastapi.tiangolo.com/advanced/events/
"""
client: AsyncOpenAI | None = None

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important to note that the use of | as a Union operator is supported starting from Python 3.10, as detailed in PEP 604. To ensure broader compatibility, especially with versions as early as Python 3.7, I recommend updating the code to use an alternative approach that aligns with the capabilities of these earlier Python versions


def __set_new_session(self) -> None:
if self.client is None:
self.client = AsyncOpenAI()

def init(self) -> None:
self.__set_new_session()

async def close(self) -> None:
if self.client is not None:
await self.client.close()
self.client = None

def __call__(self) -> AsyncOpenAI:
self.__set_new_session()
assert self.client is not None
return self.client

aio_client = AioClient()

@asynccontextmanager
async def lifespan(app: FastAPI):
aio_client.init()
yield
await aio_client.close()

app = FastAPI(lifespan=lifespan)

@app.get("/foo")
async def foo(aio_client: AsyncOpenAI = Depends(aio_client)) -> str:
res = await aio_client.chat.completions.create(...)
...
return "ok"
```

## Using types

Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev), which provide helper methods for things like:
Expand Down