instructor
84 строки · 2.4 Кб
1from pydantic import BaseModel
2from fastapi import FastAPI
3from openai import AsyncOpenAI
4import instructor
5import logfire
6import asyncio
7from collections.abc import Iterable
8from fastapi.responses import StreamingResponse
9
10
11class UserData(BaseModel):
12query: str
13
14
15class MultipleUserData(BaseModel):
16queries: list[str]
17
18
19class UserDetail(BaseModel):
20name: str
21age: int
22
23
24app = FastAPI()
25openai_client = AsyncOpenAI()
26logfire.configure(pydantic_plugin=logfire.PydanticPlugin(record="all"))
27logfire.instrument_fastapi(app)
28logfire.instrument_openai(openai_client)
29client = instructor.from_openai(openai_client)
30
31
32@app.post("/user", response_model=UserDetail)
33async def endpoint_function(data: UserData) -> UserDetail:
34user_detail = await client.chat.completions.create(
35model="gpt-3.5-turbo",
36response_model=UserDetail,
37messages=[
38{"role": "user", "content": f"Extract: `{data.query}`"},
39],
40)
41logfire.info("/User returning", value=user_detail)
42return user_detail
43
44
45@app.post("/many-users", response_model=list[UserDetail])
46async def extract_many_users(data: MultipleUserData):
47async def extract_user(query: str):
48user_detail = await client.chat.completions.create(
49model="gpt-3.5-turbo",
50response_model=UserDetail,
51messages=[
52{"role": "user", "content": f"Extract: `{query}`"},
53],
54)
55logfire.info("/User returning", value=user_detail)
56return user_detail
57
58coros = [extract_user(query) for query in data.queries]
59return await asyncio.gather(*coros)
60
61
62@app.post("/extract", response_class=StreamingResponse)
63async def extract(data: UserData):
64supressed_client = AsyncOpenAI()
65logfire.instrument_openai(supressed_client, suppress_other_instrumentation=False)
66client = instructor.from_openai(supressed_client)
67users = await client.chat.completions.create(
68model="gpt-3.5-turbo",
69response_model=Iterable[UserDetail],
70stream=True,
71messages=[
72{"role": "user", "content": data.query},
73],
74)
75
76async def generate():
77with logfire.span("Generating User Response Objects"):
78async for user in users:
79resp_json = user.model_dump_json()
80logfire.info("Returning user object", value=resp_json)
81
82yield resp_json
83
84return StreamingResponse(generate(), media_type="text/event-stream")
85