instructor icon indicating copy to clipboard operation
instructor copied to clipboard

Streaming [lists of structured objects] is broken

Open elisescu opened this issue 8 months ago • 0 comments

Streaming seems to be broken.

I tried the Basic List Streaming example in a completely new and clean environment (Python 3.12.5 with venv and only a pip install instructor) and it fails with:

$ python test.py
Traceback (most recent call last):
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/retry.py", line 174, in retry_sync
    return process_response(  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/process_response.py", line 172, in process_response
    model = response_model.from_response(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/function_calls.py", line 232, in from_response
    if not completion.choices:
           ^^^^^^^^^^^^^^^^^^
AttributeError: 'Stream' object has no attribute 'choices'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/retry.py", line 163, in retry_sync
    for attempt in max_retries:
                   ^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/tenacity/__init__.py", line 445, in __iter__
    do = self.iter(retry_state=retry_state)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/tenacity/__init__.py", line 378, in iter
    result = action(retry_state)
             ^^^^^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/tenacity/__init__.py", line 421, in exc_check
    raise retry_exc from fut.exception()
tenacity.RetryError: RetryError[<Future at 0x104226f30 state=finished raised AttributeError>]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/elisescu/tmp/aaa/test.py", line 15, in <module>
    for book in client.chat.completions.create(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/client.py", line 180, in create
    return self.create_fn(
           ^^^^^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/patch.py", line 193, in new_create_sync
    response = retry_sync(
               ^^^^^^^^^^^
  File "/Users/elisescu/tmp/aaa/venv/lib/python3.12/site-packages/instructor/retry.py", line 194, in retry_sync
    raise InstructorRetryException(
instructor.exceptions.InstructorRetryException: 'Stream' object has no attribute 'choices'



$ cat test.py
from typing import List
import instructor
from openai import OpenAI
from pydantic import BaseModel, Field

# Initialize the client
client = instructor.from_openai(OpenAI())

class Book(BaseModel):
    title: str = Field(..., description="Book title")
    author: str = Field(..., description="Book author")
    year: int = Field(..., description="Publication year")

# Stream a list of books
for book in client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "List 5 classic science fiction books"}
    ],
    response_model=List[Book],  # Note: Using List directly
    stream=True
):
    print(f"Received: {book.title} by {book.author} ({book.year})")

elisescu avatar Apr 25 '25 13:04 elisescu