참고소스 수정본

This commit is contained in:
LASTA_DEV01\lasta
2026-05-12 19:40:31 +09:00
parent 0f34a451fc
commit 2e9204243d
8708 changed files with 3259488 additions and 869 deletions

View File

@@ -0,0 +1,29 @@
from __future__ import annotations
import base64
import pytest
@pytest.fixture(scope="session")
def tiny_png_bytes() -> bytes:
return base64.b64decode(
b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMA"
b"ASsJTYQAAAAASUVORK5CYII="
)
@pytest.fixture(scope="session")
def tiny_png_data_url(tiny_png_bytes: bytes) -> str:
return "data:image/png;base64," + base64.b64encode(tiny_png_bytes).decode("utf-8")
@pytest.fixture(scope="session")
def image_url() -> str:
# Public test asset used across the suite
return "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/image.jpg"
@pytest.fixture(scope="session")
def tiny_pdf_bytes() -> bytes:
return base64.b64decode(
b"JVBERi0xLjQKJSVPRgoAAAAQAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
)

View File

@@ -0,0 +1,20 @@
from __future__ import annotations
from instructor.providers.bedrock.utils import _to_bedrock_content_items
def test_bedrock_native_text_passthrough():
content = [{"text": "Bedrock-native text"}]
items = _to_bedrock_content_items(content)
assert items == [{"text": "Bedrock-native text"}]
def test_bedrock_native_image_passthrough(tiny_png_bytes: bytes):
native = {"image": {"format": "png", "source": {"bytes": tiny_png_bytes}}}
items = _to_bedrock_content_items([native])
assert items[0] == native
def test_bedrock_native_document_passthrough(tiny_pdf_bytes: bytes):
native = {"document": {"format": "pdf", "source": {"bytes": tiny_pdf_bytes}}}
items = _to_bedrock_content_items([native])
assert items[0] == native

View File

@@ -0,0 +1,26 @@
from __future__ import annotations
import pytest
from instructor.providers.bedrock.utils import _normalize_bedrock_image_format
@pytest.mark.parametrize(
"inp,expected",
[
("image/jpeg", "jpeg"),
("image/jpg", "jpeg"),
("jpg", "jpeg"),
("jpeg", "jpeg"),
("image/pjpeg", "jpeg"),
("image/png", "png"),
("png", "png"),
("image/gif", "gif"),
("gif", "gif"),
("image/webp", "webp"),
("webp", "webp"),
("", "jpeg"),
(None, "jpeg"),
("image/whatever", "jpeg"),
],
)
def test_normalize_bedrock_image_format(inp, expected):
assert _normalize_bedrock_image_format(inp) == expected

View File

@@ -0,0 +1,52 @@
from __future__ import annotations
import base64
import pytest
from instructor.providers.bedrock.utils import (
_openai_image_part_to_bedrock,
_to_bedrock_content_items,
)
def test_openai_image_part_to_bedrock_data_url(tiny_png_data_url: str):
part = {"type": "image_url", "image_url": {"url": tiny_png_data_url}}
out = _openai_image_part_to_bedrock(part)
assert "image" in out
assert out["image"]["format"] in {"png", "jpeg", "gif", "webp"} # png expected
assert out["image"]["source"]["bytes"] == base64.b64decode(
tiny_png_data_url.split(",", 1)[1]
)
def test_openai_image_part_to_bedrock_https(image_url: str):
part = {"type": "image_url", "image_url": {"url": image_url}}
out = _openai_image_part_to_bedrock(part)
assert "image" in out
# GitHub raw returns jpeg for the sample. Normalize is handled in utils.
assert out["image"]["format"] in {"jpeg", "png", "gif", "webp"}
assert isinstance(out["image"]["source"]["bytes"], (bytes, bytearray))
assert len(out["image"]["source"]["bytes"]) > 0
@pytest.mark.parametrize(
"text_part",
[
{"type": "text", "text": "What is in this image?"},
{"type": "input_text", "text": "Describe the image."},
],
)
@pytest.mark.parametrize("image_kind", ["data", "https"])
def test_to_bedrock_content_items_openai_combo(
text_part, image_kind, tiny_png_data_url: str, image_url: str
):
if image_kind == "data":
image_part = {"type": "image_url", "image_url": {"url": tiny_png_data_url}}
else:
image_part = {"type": "image_url", "image_url": {"url": image_url}}
content = [text_part, image_part]
items = _to_bedrock_content_items(content)
assert items[0] == {"text": text_part["text"]}
assert "image" in items[1]
assert isinstance(items[1]["image"]["source"]["bytes"], (bytes, bytearray))
assert len(items[1]["image"]["source"]["bytes"]) > 0

View File

@@ -0,0 +1,59 @@
from __future__ import annotations
import pytest
from instructor.providers.bedrock.utils import _prepare_bedrock_converse_kwargs_internal
def test_prepare_bedrock_kwargs_openai_text_plus_image(tiny_png_data_url: str):
call_kwargs = {
"model": "anthropic.claude-3-5-sonnet",
"temperature": 0.3,
"max_tokens": 256,
"top_p": 0.9,
"stop": ["<END>"],
"system": [{"text": "You are helpful."}],
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "hi"},
{"type": "image_url", "image_url": {"url": tiny_png_data_url}},
],
},
],
}
out = _prepare_bedrock_converse_kwargs_internal(call_kwargs)
assert out["modelId"] == "anthropic.claude-3-5-sonnet"
inf = out["inferenceConfig"]
assert inf["temperature"] == 0.3
assert inf["maxTokens"] == 256
assert inf["topP"] == 0.9
assert inf["stopSequences"] == ["<END>"]
assert out["system"][0]["text"] == "You are helpful."
parts = out["messages"][0]["content"]
assert parts[0] == {"text": "hi"}
assert parts[1]["image"]["format"] in {"jpeg", "png", "gif", "webp"}
assert isinstance(parts[1]["image"]["source"]["bytes"], (bytes, bytearray))
assert len(parts[1]["image"]["source"]["bytes"]) > 0
def test_prepare_bedrock_kwargs_openai_image_url_rejects_http():
"""Remote HTTP(S) URLs are not fetched (SSRF prevention) — must use data: URLs."""
call_kwargs = {
"model": "anthropic.claude-3-5-sonnet",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"url": "https://example.com/image.jpg"},
}
],
}
],
}
with pytest.raises(ValueError, match="Unsupported image_url scheme for Bedrock"):
_prepare_bedrock_converse_kwargs_internal(call_kwargs)