💭 chatspec
Tiny types & utilities built for the OpenAI Chat Completions API specification.

Hammad Saeed ~ @hsaeed3
📦 Installation
pip install chatspec
📚 Documentation & Examples
chatspec
provides a 'prethora' (as many as would actually be useful) of types, models & methods for validating, converting and augmenting objects used in the OpenAI chat completions API specification, as well as a MockAI
client & mock_completion()
method for creating mock llm responses quickly. I use Instructor for all of my structured outputs, so Pydantic
is a core part of this library. The point of this library is to provide a common interface for methods that I have found myself needing to replicate across multiple projects.
✨ Quickstart
import chatspec
def get_capital(city : str) -> str:
return "Paris"
stream = chatspec.mock_completion(
messages = chatspec.normalize_messages("What is the capital of France?"),
tools = [chatspec.convert_to_tool(get_capital)],
stream = True
)
chatspec.print_stream(stream)
📝 Table of Contents
🥸 Mock Completions
chatspec
provides both async
& synchronous
mock completion methods with support for streaming,
simulated tool calls, all with proper typing and overloading for response types.
stream = mock_completion(
messages=[{"role": "user", "content": "Hello, how are you?"}],
model="gpt-4o-mini",
stream=True,
)
chatspec.print_stream(stream)
mock_completion(
messages=[
{"role": "user", "content": "What is the capital of France?"}
],
model="gpt-4o-mini",
tools=[
{
"type": "function",
"function": {
"name": "get_capital",
"description": "Get the capital of France",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
}
},
},
}
],
)
Output
Completion(
id='85aa7221-54db-4ee1-90a4-8b467c90bd02',
choices=[
Choice(
message=CompletionMessage(
role='assistant',
content='Mock response to: What is the capital of France?',
name=None,
function_call=None,
tool_calls=[
CompletionToolCall(
id='17825e39-a2eb-430f-9f2a-7db467d1ec16',
type='function',
function=CompletionFunction(name='get_capital', arguments='{"city": "mock_string"}')
)
],
tool_call_id=None
),
finish_reason='tool_calls',
index=0,
logprobs=None
)
],
created=1739599399,
model='gpt-4o-mini',
object='chat.completion',
service_tier=None,
system_fingerprint=None,
usage=None
)
💬 Chat Messages
chatspec
provides a variety of utility when working with Message
objects. These methods can be used for validation, conversion, creation of
specific message types & more.
Instance Checking & Validation of Messages
import chatspec
chatspec.is_message(
{
"role" : "assistant",
"content" : "Hello, how are you?",
"tool_calls" : [
{
"id" : "123",
"function" : {"name" : "my_function", "arguments" : "{}"}
}
]
}
)
chatspec.is_message(
{"role": "user", "context": "Hello, how are you?"}
)
Validation & Normalization of Messages
& System Prompts
import chatspec
chatspec.normalize_messages("Hello!")
chatspec.normalize_messages({
"role" : "system",
"content" : "You are a helpful assistant."
})
chatspec.normalize_system_prompt(
[
{"role": "user", "content": "Hello!"},
{"role": "assistant", "content": "Hello!"}
],
system_prompt = "You are a helpful assistant."
)
chatspec.normalize_system_prompt(
[
{"role": "user", "content": "Hello!"},
{"role": "system", "content": "You are a helpful"},
{"role": "system", "content": "assistant."}
],
)
Convert or Create Specific Message
Types
Using one of the various create_*_message
methods, you can easily convert to or create specific Message
types.
import chatspec
chatspec.create_tool_message()
chatspec.create_image_message()
chatspec.create_input_audio_message()
🔧 Tools & Tool Calling
Instance Checking & Validation of Tools
Same as the Message
types, tools can be validated using the is_tool
method.
import chatspec
my_tool = {
"type": "function",
"function": {
"name": "my_function",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Some properties"
}
}
}
}
}
chatspec.is_tool(my_tool)
chatspec.is_tool({})
Convert Python Functions
, Pydantic Models
, Dataclasses
& more to Tools
import chatspec
def my_tool(x : str) -> str:
return x
chatspec.convert_to_tool(my_tool)
def my_tool(x : str) -> str:
"""
A tool with some glorious purpose.
Args:
x (str): The input to the tool.
Returns:
str: The output of the tool.
"""
return x
chatspec.convert_to_tool(my_tool)
Interacting with Tool Calls
in Completions
& Executing Tools
import chatspec
chatspec.has_tool_call()
chatspec.get_tool_calls(completion)
chatspec.run_tool(completion, my_tool)
chatspec.create_tool_message(completion, my_tool_output)
✨ Completion Responses & Streams
Instance Checking & Validation of Completions
& Streams
import chatspec
chatspec.is_completion(completion)
chatspec.is_stream(stream)
The Stream Passthrough
& Stream
Specific Methods
chatspec
provides an internal system for caching & storing stream responses from chat completions, for use & reuse for any of the methods
within this library for streams. This is helpful, as the user is able to send/display the initial stream response to the client, while still
being able to use it internally for any other use case.
import chatspec
from openai import OpenAI
client = OpenAI()
stream = chatspec.stream_passthrough(client.chat.completions.create(
messages = [{"role": "user", "content": "Hello, how are you?"}],
model = "gpt-4o-mini",
stream = True,
))
chatspec.is_stream(stream)
chatspec.dump_stream_to_message(stream)
🆉 Types & Parameters
Use any of the provided types & models for schema reference, as well as quick parameter collection & validation with the Params
model,
as well as a few specific parameter types for quick use.
from chatspec import Params
from chatspec.params import MessagesParam, StreamOptionsParam
params = Params(
messages = [{"role": "user", "content": "Hello, how are you?"}],
model = "gpt-4o-mini",
temperature = 0.5,
)
from chatspec.types import Message, Tool, ToolCall, Completion
message = Message(role = "user", content = "Hello, how are you?")
𝌭 Pydantic Models & Structured Outputs
Documentation coming soon!
📕 Markdown Formatting
Documentation coming soon!