Spaces:
Paused
Paused
| import asyncio | |
| import json | |
| import os | |
| import sys | |
| import traceback | |
| from unittest.mock import AsyncMock, MagicMock, patch | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| sys.path.insert( | |
| 0, os.path.abspath("../..") | |
| ) # Adds the parent directory to the system-path | |
| import logging | |
| import time | |
| import pytest | |
| from typing import Optional | |
| import litellm | |
| from litellm import create_batch, create_file | |
| from litellm._logging import verbose_logger | |
| from litellm.batches.batch_utils import ( | |
| _batch_cost_calculator, | |
| _get_file_content_as_dictionary, | |
| _get_batch_job_cost_from_file_content, | |
| _get_batch_job_total_usage_from_file_content, | |
| _get_batch_job_usage_from_response_body, | |
| _get_response_from_batch_job_output_file, | |
| _batch_response_was_successful, | |
| ) | |
| def sample_file_content(): | |
| return b""" | |
| {"id": "batch_req_6769ca596b38819093d7ae9f522de924", "custom_id": "request-1", "response": {"status_code": 200, "request_id": "07bc45ab4e7e26ac23a0c949973327e7", "body": {"id": "chatcmpl-AhjSMl7oZ79yIPHLRYgmgXSixTJr7", "object": "chat.completion", "created": 1734986202, "model": "gpt-4o-mini-2024-07-18", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello! How can I assist you today?", "refusal": null}, "logprobs": null, "finish_reason": "stop"}], "usage": {"prompt_tokens": 20, "completion_tokens": 10, "total_tokens": 30, "prompt_tokens_details": {"cached_tokens": 0, "audio_tokens": 0}, "completion_tokens_details": {"reasoning_tokens": 0, "audio_tokens": 0, "accepted_prediction_tokens": 0, "rejected_prediction_tokens": 0}}, "system_fingerprint": "fp_0aa8d3e20b"}}, "error": null} | |
| {"id": "batch_req_6769ca597e588190920666612634e2b4", "custom_id": "request-2", "response": {"status_code": 200, "request_id": "82e04f4c001fe2c127cbad199f5fd31b", "body": {"id": "chatcmpl-AhjSNgVB4Oa4Hq0NruTRsBaEbRWUP", "object": "chat.completion", "created": 1734986203, "model": "gpt-4o-mini-2024-07-18", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello! What can I do for you today?", "refusal": null}, "logprobs": null, "finish_reason": "length"}], "usage": {"prompt_tokens": 22, "completion_tokens": 10, "total_tokens": 32, "prompt_tokens_details": {"cached_tokens": 0, "audio_tokens": 0}, "completion_tokens_details": {"reasoning_tokens": 0, "audio_tokens": 0, "accepted_prediction_tokens": 0, "rejected_prediction_tokens": 0}}, "system_fingerprint": "fp_0aa8d3e20b"}}, "error": null} | |
| """ | |
| def sample_file_content_dict(): | |
| return [ | |
| { | |
| "id": "batch_req_6769ca596b38819093d7ae9f522de924", | |
| "custom_id": "request-1", | |
| "response": { | |
| "status_code": 200, | |
| "request_id": "07bc45ab4e7e26ac23a0c949973327e7", | |
| "body": { | |
| "id": "chatcmpl-AhjSMl7oZ79yIPHLRYgmgXSixTJr7", | |
| "object": "chat.completion", | |
| "created": 1734986202, | |
| "model": "gpt-4o-mini-2024-07-18", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "message": { | |
| "role": "assistant", | |
| "content": "Hello! How can I assist you today?", | |
| "refusal": None, | |
| }, | |
| "logprobs": None, | |
| "finish_reason": "stop", | |
| } | |
| ], | |
| "usage": { | |
| "prompt_tokens": 20, | |
| "completion_tokens": 10, | |
| "total_tokens": 30, | |
| "prompt_tokens_details": { | |
| "cached_tokens": 0, | |
| "audio_tokens": 0, | |
| }, | |
| "completion_tokens_details": { | |
| "reasoning_tokens": 0, | |
| "audio_tokens": 0, | |
| "accepted_prediction_tokens": 0, | |
| "rejected_prediction_tokens": 0, | |
| }, | |
| }, | |
| "system_fingerprint": "fp_0aa8d3e20b", | |
| }, | |
| }, | |
| "error": None, | |
| }, | |
| { | |
| "id": "batch_req_6769ca597e588190920666612634e2b4", | |
| "custom_id": "request-2", | |
| "response": { | |
| "status_code": 200, | |
| "request_id": "82e04f4c001fe2c127cbad199f5fd31b", | |
| "body": { | |
| "id": "chatcmpl-AhjSNgVB4Oa4Hq0NruTRsBaEbRWUP", | |
| "object": "chat.completion", | |
| "created": 1734986203, | |
| "model": "gpt-4o-mini-2024-07-18", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "message": { | |
| "role": "assistant", | |
| "content": "Hello! What can I do for you today?", | |
| "refusal": None, | |
| }, | |
| "logprobs": None, | |
| "finish_reason": "length", | |
| } | |
| ], | |
| "usage": { | |
| "prompt_tokens": 22, | |
| "completion_tokens": 10, | |
| "total_tokens": 32, | |
| "prompt_tokens_details": { | |
| "cached_tokens": 0, | |
| "audio_tokens": 0, | |
| }, | |
| "completion_tokens_details": { | |
| "reasoning_tokens": 0, | |
| "audio_tokens": 0, | |
| "accepted_prediction_tokens": 0, | |
| "rejected_prediction_tokens": 0, | |
| }, | |
| }, | |
| "system_fingerprint": "fp_0aa8d3e20b", | |
| }, | |
| }, | |
| "error": None, | |
| }, | |
| ] | |
| def test_get_file_content_as_dictionary(sample_file_content): | |
| result = _get_file_content_as_dictionary(sample_file_content) | |
| assert len(result) == 2 | |
| assert result[0]["id"] == "batch_req_6769ca596b38819093d7ae9f522de924" | |
| assert result[0]["custom_id"] == "request-1" | |
| assert result[0]["response"]["status_code"] == 200 | |
| assert result[0]["response"]["body"]["usage"]["total_tokens"] == 30 | |
| def test_get_batch_job_total_usage_from_file_content(sample_file_content_dict): | |
| usage = _get_batch_job_total_usage_from_file_content( | |
| sample_file_content_dict, custom_llm_provider="openai" | |
| ) | |
| assert usage.total_tokens == 62 # 30 + 32 | |
| assert usage.prompt_tokens == 42 # 20 + 22 | |
| assert usage.completion_tokens == 20 # 10 + 10 | |
| async def test_batch_cost_calculator(sample_file_content_dict): | |
| """ | |
| mock litellm.completion_cost to return 0.5 | |
| we know sample_file_content_dict has 2 successful responses | |
| so we expect the cost to be 0.5 * 2 = 1.0 | |
| """ | |
| with patch("litellm.completion_cost", return_value=0.5): | |
| cost = await _batch_cost_calculator( | |
| file_content_dictionary=sample_file_content_dict, | |
| custom_llm_provider="openai", | |
| ) | |
| assert cost == 1.0 # 0.5 * 2 successful responses | |
| def test_get_response_from_batch_job_output_file(sample_file_content_dict): | |
| result = _get_response_from_batch_job_output_file(sample_file_content_dict[0]) | |
| assert result["id"] == "chatcmpl-AhjSMl7oZ79yIPHLRYgmgXSixTJr7" | |
| assert result["object"] == "chat.completion" | |
| assert result["usage"]["total_tokens"] == 30 | |