comminity[patch]: fix #25575 YandexGPTs for _grpc_metadata (#25617)

it fixes two issues:

### YGPTs are broken #25575

```
File ....conda/lib/python3.11/site-packages/langchain_community/embeddings/yandex.py:211, in _make_request(self, texts, **kwargs)
..
--> 211 res = stub.TextEmbedding(request, metadata=self._grpc_metadata)  # type: ignore[attr-defined]

AttributeError: 'YandexGPTEmbeddings' object has no attribute '_grpc_metadata'
```
My gut feeling that #23841 is the cause.

I have to drop leading underscore from `_grpc_metadata` for quickfix,
but I just don't know how to do it _pydantic_ enough.

### minor issue:

if we use `api_key`, which is not the best practice the code fails with 

```
File ~/git/...../python3.11/site-packages/langchain_community/embeddings/yandex.py:119, in YandexGPTEmbeddings.validate_environment(cls, values)
...

AttributeError: 'tuple' object has no attribute 'append'
```

- Added new integration test. But it requires YGPT env available and
active account. I don't know how int tests dis\enabled in CI.
 - added small unit tests with mocks. Should be fine.

---------

Co-authored-by: mikhail-khludnev <mikhail_khludnev@rntgroup.com>
This commit is contained in:
Mikhail Khludnev
2024-08-29 04:48:10 +03:00
committed by GitHub
parent 850bf89e48
commit a017f49fd3
7 changed files with 297 additions and 20 deletions

View File

@@ -57,7 +57,7 @@ class _BaseYandexGPT(Serializable):
disable_request_logging: bool = False
"""YandexGPT API logs all request data by default.
If you provide personal data, confidential information, disable logging."""
_grpc_metadata: Optional[Sequence] = None
grpc_metadata: Optional[Sequence] = None
@property
def _llm_type(self) -> str:
@@ -92,15 +92,15 @@ class _BaseYandexGPT(Serializable):
raise ValueError("Either 'YC_API_KEY' or 'YC_IAM_TOKEN' must be provided.")
if values["iam_token"]:
values["_grpc_metadata"] = [
values["grpc_metadata"] = [
("authorization", f"Bearer {values['iam_token'].get_secret_value()}")
]
if values["folder_id"]:
values["_grpc_metadata"].append(("x-folder-id", values["folder_id"]))
values["grpc_metadata"].append(("x-folder-id", values["folder_id"]))
else:
values["_grpc_metadata"] = (
values["grpc_metadata"] = [
("authorization", f"Api-Key {values['api_key'].get_secret_value()}"),
)
]
if values["model_uri"] == "" and values["folder_id"] == "":
raise ValueError("Either 'model_uri' or 'folder_id' must be provided.")
if not values["model_uri"]:
@@ -108,7 +108,7 @@ class _BaseYandexGPT(Serializable):
f"gpt://{values['folder_id']}/{values['model_name']}/{values['model_version']}"
)
if values["disable_request_logging"]:
values["_grpc_metadata"].append(
values["grpc_metadata"].append(
(
"x-data-logging-enabled",
"false",
@@ -235,7 +235,7 @@ def _make_request(
messages=[Message(role="user", text=prompt)],
)
stub = TextGenerationServiceStub(channel)
res = stub.Completion(request, metadata=self._grpc_metadata) # type: ignore[attr-defined]
res = stub.Completion(request, metadata=self.grpc_metadata) # type: ignore[attr-defined]
return list(res)[0].alternatives[0].message.text
@@ -291,7 +291,7 @@ async def _amake_request(self: YandexGPT, prompt: str) -> str:
messages=[Message(role="user", text=prompt)],
)
stub = TextGenerationAsyncServiceStub(channel)
operation = await stub.Completion(request, metadata=self._grpc_metadata) # type: ignore[attr-defined]
operation = await stub.Completion(request, metadata=self.grpc_metadata) # type: ignore[attr-defined]
async with grpc.aio.secure_channel(
operation_api_url, channel_credentials
) as operation_channel:
@@ -301,7 +301,7 @@ async def _amake_request(self: YandexGPT, prompt: str) -> str:
operation_request = GetOperationRequest(operation_id=operation.id)
operation = await operation_stub.Get(
operation_request,
metadata=self._grpc_metadata, # type: ignore[attr-defined]
metadata=self.grpc_metadata, # type: ignore[attr-defined]
)
completion_response = CompletionResponse()