mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
refactor(ocr): resolve logging executor explicitly
This commit is contained in:
parent
a5ab6f5af3
commit
09045c5162
3 changed files with 35 additions and 2 deletions
|
|
@ -51,6 +51,7 @@ class CompletionExecutor(Protocol):
|
|||
def submit(
|
||||
self,
|
||||
function: Callable[..., object],
|
||||
/,
|
||||
*args: object,
|
||||
) -> Future[object]: ...
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@ import contextvars
|
|||
import datetime
|
||||
import weakref
|
||||
from collections.abc import Callable, Coroutine
|
||||
from concurrent.futures import Future
|
||||
from concurrent.futures import Future, ThreadPoolExecutor
|
||||
from importlib import import_module
|
||||
from threading import get_ident
|
||||
from typing import Final
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
import litellm
|
||||
from litellm.litellm_core_utils import thread_pool_executor
|
||||
from litellm.litellm_core_utils.call_completion import CallCompletion, PythonCompletion
|
||||
from litellm.llms.base_llm.ocr.transformation import OCRResponse
|
||||
from litellm.rust_bridge import ocr as rust_ocr_bridge
|
||||
|
|
@ -128,6 +130,35 @@ def test_python_completion_preserves_sync_context_and_response_identity() -> Non
|
|||
assert len(executor.submissions) == 1
|
||||
|
||||
|
||||
def test_sync_wrapper_dispatches_with_logging_executor_and_caller_context(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
marker: Final[contextvars.ContextVar[str]] = contextvars.ContextVar("wrapper-context", default="missing")
|
||||
marker.set("request-context")
|
||||
caller_thread: Final = get_ident()
|
||||
response: Final = object()
|
||||
observed: Final[list[tuple[object, str, int]]] = []
|
||||
logging_obj: Final = MagicMock()
|
||||
|
||||
def record_success(result: object, start_time: datetime.datetime, end_time: datetime.datetime) -> None:
|
||||
observed.append((result, marker.get(), get_ident()))
|
||||
|
||||
def ocr(**kwargs: object) -> object:
|
||||
return response
|
||||
|
||||
logging_obj.success_handler.side_effect = record_success
|
||||
monkeypatch.setattr("litellm.utils.function_setup", MagicMock(return_value=(logging_obj, {})))
|
||||
monkeypatch.setattr("litellm.utils.load_credentials_from_list", MagicMock())
|
||||
wrapped: Final = client(ocr)
|
||||
with ThreadPoolExecutor(max_workers=1) as executor:
|
||||
monkeypatch.setattr(thread_pool_executor, "executor", executor)
|
||||
result: Final = wrapped()
|
||||
|
||||
assert result is response
|
||||
assert len(observed) == 1
|
||||
assert observed[0][0] is response
|
||||
assert observed[0][1] == "request-context"
|
||||
assert observed[0][2] != caller_thread
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_call_completion_attaches_once_and_forwards_final_objects() -> None:
|
||||
python_completion: Final = RecordingCompletion()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import pytest_asyncio
|
|||
|
||||
import litellm
|
||||
from litellm import utils
|
||||
from litellm.litellm_core_utils import litellm_logging
|
||||
from litellm.litellm_core_utils import litellm_logging, thread_pool_executor
|
||||
from litellm.litellm_core_utils.logging_worker import GLOBAL_LOGGING_WORKER
|
||||
from litellm.rust_bridge.configuration import ( # pyright: ignore[reportPrivateUsage] # preserve raw configuration state in test isolation
|
||||
_CONFIGURATION,
|
||||
|
|
@ -77,6 +77,7 @@ async def isolate_ocr_test_state() -> AsyncIterator[None]:
|
|||
stack.enter_context(_rebound(_CONFIGURATION, "override", None))
|
||||
executor: Final = ThreadPoolExecutor(thread_name_prefix="rust-ocr-test-logging")
|
||||
stack.enter_context(_rebound(utils, "executor", executor))
|
||||
stack.enter_context(_rebound(thread_pool_executor, "executor", executor))
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue