diff --git a/src/openai/lib/_parsing/_embeddings.py b/src/openai/lib/_parsing/_embeddings.py index acb890fa52..e46fa47e35 100644 --- a/src/openai/lib/_parsing/_embeddings.py +++ b/src/openai/lib/_parsing/_embeddings.py @@ -1,5 +1,6 @@ from __future__ import annotations +import sys import array import base64 from typing import cast @@ -24,12 +25,16 @@ def parse_embedding_response( data = cast(object, embedding.embedding) if not isinstance(data, str): continue + decoded = base64.b64decode(data) if not has_numpy(): # use array for base64 optimisation - embedding.embedding = array.array("f", base64.b64decode(data)).tolist() + floats = array.array("f", decoded) + if sys.byteorder == "big": + floats.byteswap() + embedding.embedding = floats.tolist() else: embedding.embedding = np.frombuffer( # type: ignore[no-untyped-call] - base64.b64decode(data), dtype="float32" + decoded, dtype=" None: + response = make_response(ENCODED) + decoded = base64.b64decode(ENCODED) + + class Floats: + swapped = False + + def byteswap(self) -> None: + self.swapped = True + + def tolist(self) -> list[float]: + assert self.swapped + return VALUES + + floats = Floats() + + def make_array(typecode: str, initializer: bytes) -> Floats: + assert typecode == "f" + assert initializer == decoded + return floats + + monkeypatch.setattr(embeddings_parser, "has_numpy", lambda: False) + monkeypatch.setattr(embeddings_parser, "sys", SimpleNamespace(byteorder="big")) + monkeypatch.setattr(embeddings_parser.array, "array", make_array) + + parsed = embeddings_parser.parse_embedding_response(response, encoding_format=omit) + + assert parsed.data[0].embedding == VALUES + + @pytest.mark.parametrize("encoding_format", ["float", "base64", None]) @pytest.mark.parametrize("vectors", [(ENCODED,), ("abc",), ()], ids=["encoded", "invalid", "empty"]) def test_explicit_format_is_untouched(