From 8ac3e29664d07f249b46031d1898b0096a2b24e1 Mon Sep 17 00:00:00 2001 From: Renaud Date: Wed, 18 Jun 2025 20:25:26 +0200 Subject: [PATCH 1/2] feat(bedrock): improve async client using asyncio.to_thread AsyncInstructor now uses asyncio.to_thread to run the synchronous boto3 Bedrock client in a thread, enabling non-blocking async usage. Updated docstring for clarity. --- instructor/client_bedrock.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/instructor/client_bedrock.py b/instructor/client_bedrock.py index e25e4fc55..70eef9ed2 100644 --- a/instructor/client_bedrock.py +++ b/instructor/client_bedrock.py @@ -8,6 +8,8 @@ import instructor from instructor.client import AsyncInstructor, Instructor +import asyncio + @overload # type: ignore def from_bedrock( @@ -42,6 +44,21 @@ def from_bedrock( _async: bool = False, **kwargs: Any, ) -> Instructor | AsyncInstructor: + """ + Create an Instructor or AsyncInstructor client for AWS Bedrock. + + Args: + client (BaseClient): A boto3 Bedrock client instance. + mode (instructor.Mode): The mode to use (BEDROCK_TOOLS or BEDROCK_JSON). + _async (bool): If True, returns an AsyncInstructor that runs client.converse in a thread using asyncio.to_thread. + **kwargs: Additional keyword arguments passed to the Instructor/AsyncInstructor. + + Returns: + Instructor or AsyncInstructor: The appropriate client for synchronous or asynchronous usage. + + Note: + The async client is a wrapper around the synchronous boto3 client, using asyncio.to_thread to enable non-blocking calls in async applications. + """ valid_modes = { instructor.Mode.BEDROCK_TOOLS, instructor.Mode.BEDROCK_JSON, @@ -65,7 +82,7 @@ def from_bedrock( ) async def async_wrapper(**kwargs: Any): - return client.converse(**kwargs) + return await asyncio.to_thread(client.converse, **kwargs) create = client.converse From 3aa866e4f666fb31cea62ae06cb87478beaac568 Mon Sep 17 00:00:00 2001 From: Renaud Date: Wed, 18 Jun 2025 20:26:00 +0200 Subject: [PATCH 2/2] docs(bedrock): add async usage example and explanation for Bedrock integration Documented how Instructor enables async support for boto3 Bedrock client using asyncio.to_thread, with a self-contained example and clear explanation. --- docs/integrations/bedrock.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/integrations/bedrock.md b/docs/integrations/bedrock.md index 9af7f1551..c3fbdec5e 100644 --- a/docs/integrations/bedrock.md +++ b/docs/integrations/bedrock.md @@ -51,6 +51,40 @@ print(user) # > User(name='Jason', age=25) ``` +### Async Example + +AWS's boto3 Bedrock client does **not** natively support asynchronous operations. To enable async usage, Instructor wraps the synchronous client using Python's `asyncio.to_thread`, which runs blocking calls in a thread pool. This allows you to use Bedrock in async applications without blocking the event loop, but note that true network-level async is not possible until boto3 adds support. + +```python +import boto3 +import instructor +from pydantic import BaseModel +import asyncio + +# Initialize the Bedrock client +bedrock_client = boto3.client('bedrock-runtime') + +# Enable instructor patches for Bedrock client (async) +client = instructor.from_bedrock(bedrock_client, _async=True) + +class User(BaseModel): + name: str + age: int + +async def main(): + user = await client.chat.completions.create( + modelId="anthropic.claude-3-sonnet-20240229-v1:0", + messages=[ + {"role": "user", "content": [{ "text": "Extract: Jason is 25 years old" }]}, + ], + response_model=User, + ) + print(user) + # > User(name='Jason', age=25) + +asyncio.run(main()) +``` + ## Supported Modes AWS Bedrock supports the following modes with Instructor: