Py2OpenAI
A Python library that automatically converts Python functions to OpenAI function calling schemas.
OpenAI Function Schema Generator
Convert Python functions to OpenAI-compatible function schemas automatically.
Installation
pip install py2openai
Basic Usage
from py2openai import create_schema
from typing import Literal
def get_weather(
location: str,
unit: Literal["C", "F"] = "C",
detailed: bool = False,
) -> dict[str, str | float]:
"""Get the weather for a location.
Args:
location: City or address to get weather for
unit: Temperature unit (Celsius or Fahrenheit)
detailed: Include extended forecast
"""
return {"temp": 22.5, "conditions": "sunny"}
# Create schema
schema = create_schema(get_weather)
# The schema.model_dump_openai() returns a TypedDict with the complete OpenAI tool definition:
# OpenAIFunctionTool = TypedDict({
# "type": Literal["function"],
# "function": OpenAIFunctionDefinition
# })
# Use with OpenAI
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "What's the weather in London?"}],
tools=[schema.model_dump_openai()], # Schema includes the type: "function" wrapper
tool_choice="auto"
)
Note: This library supports the OpenAI API v1 format (openai>=1.0.0). For older versions of the OpenAI package that use the legacy functions API, you'll need to unwrap the function definition using
schema.model_dump_openai()["function"].
## Supported Types
### Basic Types
```python
def func(
text: str, # -> "type": "string"
number: int, # -> "type": "integer"
amount: float, # -> "type": "number"
enabled: bool, # -> "type": "boolean"
anything: Any, # -> "type": "string"
) -> None: ...
Container Types
def func(
items: list[str], # -> "type": "array", "items": {"type": "string"}
numbers: set[int], # -> same as list
mapping: dict[str, Any], # -> "type": "object", "additionalProperties": true
nested: list[dict[str, int]], # -> nested array/object types
sequence: Sequence[str], # -> "type": "array"
collection: Collection[int], # -> "type": "array"
) -> None: ...
Enums and Literals
class Color(Enum):
RED = "red"
BLUE = "blue"
def func(
color: Color, # -> "type": "string", "enum": ["red", "blue"]
mode: Literal["fast", "slow"], # -> "type": "string", "enum": ["fast", "slow"]
) -> None: ...
Optional and Union Types
def func(
opt1: str | None, # -> "type": "string"
opt2: int | None, # -> "type": "integer"
union: str | int, # -> "type": "string" (first type)
) -> None: ...
Custom Types
@dataclass
class User:
name: str
age: int
def func(
user: User, # -> "type": "object"
data: JsonDict, # -> "type": "object"
) -> None: ...
Type Aliases
JsonValue = dict[str, Any] | list[Any] | str | int | float | bool | None
JsonDict = dict[str, JsonValue]
def func(
data: JsonDict, # -> "type": "object"
values: list[JsonValue], # -> "type": "array"
) -> None: ...
Recursive Types
def func(
tree: dict[str, "dict[str, Any] | str"], # -> "type": "object"
nested: dict[str, list["dict[str, Any]"]], # -> "type": "object"
) -> None: ...
Generated Schema Example
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the weather for a location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City or address to get weather for"
},
"unit": {
"type": "string",
"enum": ["C", "F"],
"description": "Temperature unit (Celsius or Fahrenheit)",
"default": "C"
},
"detailed": {
"type": "boolean",
"description": "Include extended forecast",
"default": false
}
},
"required": ["location"]
}
}
}
Schema Generators
Module Schemas
You can generate schemas for all public functions in a module using create_schemas_from_module:
from py2openai import create_schemas_from_module
import math
# Generate schemas for all public functions
schemas = create_schemas_from_module(math)
# Generate schemas for specific functions only
schemas = create_schemas_from_module(math, include_functions=['sin', 'cos'])
# Import module by string name
schemas = create_schemas_from_module('math')
Class Schemas
Generate schemas for all public methods in a class using create_schemas_from_class:
from py2openai import create_schemas_from_class
class Calculator:
def add(self, x: int, y: int) -> int:
"""Add two numbers.
Args:
x: First number
y: Second number
Returns:
Sum of x and y
"""
return x + y
@classmethod
def multiply(cls, x: int, y: int) -> int:
"""Multiply two numbers.
Args:
x: First number
y: Second number
Returns:
Product of x and y
"""
return x * y
@staticmethod
def divide(x: float, y: float) -> float:
"""Divide two numbers.
Args:
x: Numerator
y: Denominator
Returns:
Result of x divided by y
"""
return x / y
# Generate schemas for all public methods
schemas = create_schemas_from_class(Calculator)
# Access individual method schemas
add_schema = schemas['Calculator.add']
multiply_schema = schemas['Calculator.multiply']
divide_schema = schemas['Calculator.divide']
The schema generators support:
- Regular functions
- Regular instance methods (bound and unbound)
- Class methods
- Static methods
- Decorated functions / methods
- Async functions / methods
- Property methods
- Basically all stdlib typing features as well as many stdlib types
- Method docstrings for descriptions
- Default values
- Return type hints
Diferences to pydantic schema generation
While Pydantics schema generation preserves detailed type information, schema.model_dump_openai()
simplifies types to match OpenAI's function calling format. Most special types
(datetime, UUID, Path, etc.) are handled similarly by both (we only strip unused information), but we handle enums
differently: Instead of preserving enum class information, we extract just the values
as a string enum. Union types and Optionals are also handled differently - we typically
pick the first type to keep the schema simple and practical for AI interaction.
This ensures compatibility with OpenAI's function calling API while maintaining enough
type information for the AI to understand the function signature.
Metadata
Release files for py2openai 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| py2openai-1.0.1.tar.gz | 21.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| py2openai-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.1 kB
Release files / py2openai-1.0.1.tar.gz
| Download URL | py2openai-1.0.1.tar.gz |
|---|---|
| Size | 21.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e00d235d6b959a1d06b5b79e429e2792c61bc9294ff20f273b18a2988a6c2a1a
|
|
BLAKE2b-256 checksum How to use checksums |
c7925c6d38aaa58a0e2d9b0d8929ef60d64df1629b56d40c6bdb5584cfa89f4f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2025.
Transparency logRelease files / py2openai-1.0.1-py3-none-any.whl
| Download URL | py2openai-1.0.1-py3-none-any.whl |
|---|---|
| Size | 23.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e8aa0110511680cd25cedc1615cd5950fbc6eeb3a6b4b1b8cde925f1effb18d
|
|
BLAKE2b-256 checksum How to use checksums |
65592c36e85217d4669db54afc633879047e14ef5b05f8ef0ab724a166edcfdd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2025.
Transparency log