z-ai-sdk-python/tests/unit_tests/response_model/test_response.py
wellenzheng 508eaf4f4c
fix: video example, remove finetuning\knowledge\document module (#17)
Co-authored-by: zhengweijun <weijun.zheng@aminer.cn>
2025-07-26 11:21:48 +08:00

340 lines
9.3 KiB
Python

# -*- coding: utf-8 -*-
from typing import Type
import httpx
import pytest
from zai.core import BaseModel, HttpClient
from zai.core._base_type import ResponseT
from zai.core._request_opt import FinalRequestOptions
from zai.core._response import APIResponse
from zai.types.chat.async_chat_completion import (
AsyncCompletion,
AsyncTaskStatus,
)
from zai.types.chat.chat_completion import (
Completion,
)
from zai.types.chat.chat_completion import (
CompletionChoice as ChatCompletionChoice,
)
from zai.types.chat.chat_completion import (
CompletionMessageToolCall as ChatCompletionMessageToolCall,
)
from zai.types.chat.chat_completion import (
CompletionUsage as ChatCompletionUsage,
)
from zai.types.embeddings import Embedding, EmbeddingsResponded
from zai.types.files.file_object import FileObject, ListOfFileObject
from zai.types.image import GeneratedImage, ImagesResponded
class MockClient:
_strict_response_validation: bool = False
def _process_response_data(
self,
*,
data: object,
cast_type: Type[ResponseT],
response: httpx.Response,
) -> ResponseT:
pass
@pytest.mark.parametrize(
'R',
[
AsyncTaskStatus,
AsyncCompletion,
Completion,
],
)
def test_response_chat_model_cast(R: Type[BaseModel]) -> None:
MockClient._process_response_data = HttpClient._process_response_data
response = httpx.Response(
status_code=200,
content="""{
"id": "completion123",
"request_id": "request456",
"model": "model-name",
"task_status": "completed",
"choices": [
{
"index": 0,
"finish_reason": "normal",
"message": {
"content": "This is the completion content.",
"role": "assistant",
"tool_calls": [
{
"id": "toolcall789",
"function": {
"arguments": "arg1, arg2",
"name": "functionName"
},
"type": "function_call"
}
]
}
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 15,
"total_tokens": 25
}
}""",
)
opts = FinalRequestOptions.construct(method='get', url='path')
http_response = APIResponse(
raw=response,
cast_type=R,
client=MockClient(),
stream=False,
stream_cls=None,
options=opts,
)
model = http_response.parse()
if R == AsyncTaskStatus:
assert R == model.__class__
assert isinstance(model, AsyncTaskStatus)
assert model.id == 'completion123'
assert model.request_id == 'request456'
assert model.model == 'model-name'
assert model.task_status == 'completed'
elif R == AsyncCompletion:
assert R == model.__class__
assert isinstance(model, AsyncCompletion)
assert model.id == 'completion123'
assert model.request_id == 'request456'
assert model.model == 'model-name'
assert model.task_status == 'completed'
assert isinstance(model.choices, list)
assert model.choices[0].index == 0
assert model.choices[0].finish_reason == 'normal'
assert model.choices[0].message.content == 'This is the completion content.'
assert model.choices[0].message.role == 'assistant'
assert isinstance(model.choices[0].message.tool_calls, list)
assert model.choices[0].message.tool_calls[0].id == 'toolcall789'
assert model.choices[0].message.tool_calls[0].function.arguments == 'arg1, arg2'
assert model.choices[0].message.tool_calls[0].function.name == 'functionName'
assert model.choices[0].message.tool_calls[0].type == 'function_call'
assert model.usage.prompt_tokens == 10
assert model.usage.completion_tokens == 15
assert model.usage.total_tokens == 25
elif R == Completion:
assert R == model.__class__
assert isinstance(model, Completion)
assert model.id == 'completion123'
assert model.request_id == 'request456'
assert model.model == 'model-name'
assert model.created == None
assert isinstance(model.choices, list)
assert isinstance(model.choices[0], ChatCompletionChoice)
assert model.choices[0].index == 0
assert model.choices[0].finish_reason == 'normal'
assert model.choices[0].message.content == 'This is the completion content.'
assert model.choices[0].message.role == 'assistant'
assert isinstance(model.choices[0].message.tool_calls, list)
assert isinstance(
model.choices[0].message.tool_calls[0],
ChatCompletionMessageToolCall,
)
assert model.choices[0].message.tool_calls[0].id == 'toolcall789'
assert model.choices[0].message.tool_calls[0].function.arguments == 'arg1, arg2'
assert model.choices[0].message.tool_calls[0].function.name == 'functionName'
assert model.choices[0].message.tool_calls[0].type == 'function_call'
assert isinstance(model.usage, ChatCompletionUsage)
assert model.usage.prompt_tokens == 10
assert model.usage.completion_tokens == 15
assert model.usage.total_tokens == 25
else:
assert False, f'Unexpected model type: {R}'
@pytest.mark.parametrize(
'R',
[EmbeddingsResponded],
)
def test_response_embedding_model_cast(R: Type[BaseModel]) -> None:
MockClient._process_response_data = HttpClient._process_response_data
response = httpx.Response(
status_code=200,
content="""{
"object": "embeddings",
"data": [
{
"object": "embedding",
"index": 1,
"embedding": [0.1, 0.2]
}
],
"model": "some-model-name",
"usage": {
"prompt_tokens": 20,
"completion_tokens": 30,
"total_tokens": 50
}
}""",
)
opts = FinalRequestOptions.construct(method='get', url='path')
http_response = APIResponse(
raw=response,
cast_type=R,
client=MockClient(),
stream=False,
stream_cls=None,
options=opts,
)
model = http_response.parse()
assert R == model.__class__
assert isinstance(model, EmbeddingsResponded)
assert isinstance(model.data, list)
assert isinstance(model.data[0], Embedding)
assert model.data[0].object == 'embedding'
assert model.data[0].index == 1
assert model.data[0].embedding == [0.1, 0.2]
assert model.object == 'embeddings'
assert model.model == 'some-model-name'
assert model.usage.prompt_tokens == 20
assert model.usage.completion_tokens == 30
assert model.usage.total_tokens == 50
@pytest.mark.parametrize(
'R',
[
FileObject,
],
)
def test_response_file_list_model_cast(R: Type[BaseModel]) -> None:
MockClient._process_response_data = HttpClient._process_response_data
response = httpx.Response(
status_code=200,
content=""" {
"id": "12345",
"bytes": 1024,
"created_at": 1617181723,
"filename": "example.txt",
"object": "file",
"purpose": "example purpose",
"status": "uploaded",
"status_details": "File uploaded successfully"
}""",
)
opts = FinalRequestOptions.construct(method='get', url='path')
http_response = APIResponse(
raw=response,
cast_type=R,
client=MockClient(),
stream=False,
stream_cls=None,
options=opts,
)
model = http_response.parse()
assert R == model.__class__
assert isinstance(model, FileObject)
assert model.id == '12345'
assert model.bytes == 1024
assert model.created_at == 1617181723
assert model.filename == 'example.txt'
assert model.object == 'file'
assert model.purpose == 'example purpose'
assert model.status == 'uploaded'
assert model.status_details == 'File uploaded successfully'
@pytest.mark.parametrize(
'R',
[
ListOfFileObject,
],
)
def test_response_file_list_model_cast(R: Type[BaseModel]) -> None:
MockClient._process_response_data = HttpClient._process_response_data
response = httpx.Response(
status_code=200,
content="""{
"object": "list",
"data": [
{
"id": "12345",
"bytes": 1024,
"created_at": 1617181723,
"filename": "example.txt",
"object": "file",
"purpose": "example purpose",
"status": "uploaded",
"status_details": "File uploaded successfully"
}
],
"has_more": true
}""",
)
opts = FinalRequestOptions.construct(method='get', url='path')
http_response = APIResponse(
raw=response,
cast_type=R,
client=MockClient(),
stream=False,
stream_cls=None,
options=opts,
)
model = http_response.parse()
assert R == model.__class__
assert isinstance(model.data, list)
assert isinstance(model.data[0], FileObject)
assert model.data[0].id == '12345'
assert model.data[0].bytes == 1024
assert model.data[0].created_at == 1617181723
assert model.data[0].filename == 'example.txt'
assert model.data[0].object == 'file'
assert model.data[0].purpose == 'example purpose'
assert model.data[0].status == 'uploaded'
assert model.data[0].status_details == 'File uploaded successfully'
assert model.has_more == True
@pytest.mark.parametrize('R', [ImagesResponded])
def test_response_image_model_cast(R: Type[BaseModel]) -> None:
MockClient._process_response_data = HttpClient._process_response_data
response = httpx.Response(
status_code=200,
content="""{
"created": 1234567890,
"data": [
{
"b64_json": "base64_encoded_string",
"url": "http://example.com/image.png",
"revised_prompt": "Revised prompt text"
}
]
}""",
)
opts = FinalRequestOptions.construct(method='get', url='path')
http_response = APIResponse(
raw=response,
cast_type=R,
client=MockClient(),
stream=False,
stream_cls=None,
options=opts,
)
model = http_response.parse()
assert R == model.__class__
assert isinstance(model.data, list)
assert isinstance(model.data[0], GeneratedImage)
assert model.data[0].b64_json == 'base64_encoded_string'