Name | py2openai JSON |
Version |
0.10.0
JSON |
| download |
home_page | None |
Summary | Create OpenAI-compatible function schemas from python functions |
upload_time | 2025-10-06 20:26:41 |
maintainer | None |
docs_url | None |
author | Philipp Temminghoff |
requires_python | >=3.12 |
license | MIT License
Copyright (c) 2024, Philipp Temminghoff
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
keywords |
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Py2OpenAI
A Python library that automatically converts Python functions to OpenAI function calling schemas.
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://pypi.org/project/py2openai/)
[](https://github.com/phil65/py2openai/releases)
[](https://github.com/phil65/py2openai/graphs/contributors)
[](https://github.com/phil65/py2openai/discussions)
[](https://github.com/phil65/py2openai/forks)
[](https://github.com/phil65/py2openai/issues)
[](https://github.com/phil65/py2openai/pulls)
[](https://github.com/phil65/py2openai/watchers)
[](https://github.com/phil65/py2openai/stars)
[](https://github.com/phil65/py2openai)
[](https://github.com/phil65/py2openai/commits)
[](https://github.com/phil65/py2openai/releases)
[](https://github.com/phil65/py2openai)
[](https://github.com/phil65/py2openai)
[](https://codecov.io/gh/phil65/py2openai/)
[](https://pyup.io/repos/github/phil65/py2openai/)
[Read the documentation!](https://phil65.github.io/py2openai/)
# OpenAI Function Schema Generator
Convert Python functions to OpenAI-compatible function schemas automatically.
## Installation
```bash
pip install py2openai
```
## Basic Usage
```python
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
```python
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
```python
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
```python
def func(
opt1: str | None, # -> "type": "string"
opt2: int | None, # -> "type": "integer"
union: str | int, # -> "type": "string" (first type)
) -> None: ...
```
### Custom Types
```python
@dataclass
class User:
name: str
age: int
def func(
user: User, # -> "type": "object"
data: JsonDict, # -> "type": "object"
) -> None: ...
```
### Type Aliases
```python
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
```python
def func(
tree: dict[str, "dict[str, Any] | str"], # -> "type": "object"
nested: dict[str, list["dict[str, Any]"]], # -> "type": "object"
) -> None: ...
```
## Generated Schema Example
```python
{
"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`:
```python
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`:
```python
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.
Raw data
{
"_id": null,
"home_page": null,
"name": "py2openai",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": null,
"author": "Philipp Temminghoff",
"author_email": "Philipp Temminghoff <philipptemminghoff@googlemail.com>",
"download_url": "https://files.pythonhosted.org/packages/e9/b5/a3a88aae1012cc817857f5dc248745e6947ccc63f2097f8048af837077f1/py2openai-0.10.0.tar.gz",
"platform": null,
"description": "# Py2OpenAI\n\nA Python library that automatically converts Python functions to OpenAI function calling schemas.\n\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://pypi.org/project/py2openai/)\n[](https://github.com/phil65/py2openai/releases)\n[](https://github.com/phil65/py2openai/graphs/contributors)\n[](https://github.com/phil65/py2openai/discussions)\n[](https://github.com/phil65/py2openai/forks)\n[](https://github.com/phil65/py2openai/issues)\n[](https://github.com/phil65/py2openai/pulls)\n[](https://github.com/phil65/py2openai/watchers)\n[](https://github.com/phil65/py2openai/stars)\n[](https://github.com/phil65/py2openai)\n[](https://github.com/phil65/py2openai/commits)\n[](https://github.com/phil65/py2openai/releases)\n[](https://github.com/phil65/py2openai)\n[](https://github.com/phil65/py2openai)\n[](https://codecov.io/gh/phil65/py2openai/)\n[](https://pyup.io/repos/github/phil65/py2openai/)\n\n[Read the documentation!](https://phil65.github.io/py2openai/)\n\n# OpenAI Function Schema Generator\n\nConvert Python functions to OpenAI-compatible function schemas automatically.\n\n## Installation\n\n```bash\npip install py2openai\n```\n\n## Basic Usage\n\n```python\nfrom py2openai import create_schema\nfrom typing import Literal\n\ndef get_weather(\n location: str,\n unit: Literal[\"C\", \"F\"] = \"C\",\n detailed: bool = False,\n) -> dict[str, str | float]:\n \"\"\"Get the weather for a location.\n\n Args:\n location: City or address to get weather for\n unit: Temperature unit (Celsius or Fahrenheit)\n detailed: Include extended forecast\n \"\"\"\n return {\"temp\": 22.5, \"conditions\": \"sunny\"}\n\n# Create schema\nschema = create_schema(get_weather)\n\n# The schema.model_dump_openai() returns a TypedDict with the complete OpenAI tool definition:\n# OpenAIFunctionTool = TypedDict({\n# \"type\": Literal[\"function\"],\n# \"function\": OpenAIFunctionDefinition\n# })\n\n# Use with OpenAI\nfrom openai import OpenAI\n\nclient = OpenAI()\nresponse = client.chat.completions.create(\n model=\"gpt-4\",\n messages=[{\"role\": \"user\", \"content\": \"What's the weather in London?\"}],\n tools=[schema.model_dump_openai()], # Schema includes the type: \"function\" wrapper\n tool_choice=\"auto\"\n)\n```\n\n> **Note**: This library supports the OpenAI API v1 format (openai>=1.0.0). For older\n> versions of the OpenAI package that use the legacy functions API, you'll need to\n> unwrap the function definition using `schema.model_dump_openai()[\"function\"]`.\n```\n\n## Supported Types\n\n### Basic Types\n```python\ndef func(\n text: str, # -> \"type\": \"string\"\n number: int, # -> \"type\": \"integer\"\n amount: float, # -> \"type\": \"number\"\n enabled: bool, # -> \"type\": \"boolean\"\n anything: Any, # -> \"type\": \"string\"\n) -> None: ...\n```\n\n### Container Types\n```python\ndef func(\n items: list[str], # -> \"type\": \"array\", \"items\": {\"type\": \"string\"}\n numbers: set[int], # -> same as list\n mapping: dict[str, Any], # -> \"type\": \"object\", \"additionalProperties\": true\n nested: list[dict[str, int]], # -> nested array/object types\n sequence: Sequence[str], # -> \"type\": \"array\"\n collection: Collection[int], # -> \"type\": \"array\"\n) -> None: ...\n```\n\n### Enums and Literals\n```python\nclass Color(Enum):\n RED = \"red\"\n BLUE = \"blue\"\n\ndef func(\n color: Color, # -> \"type\": \"string\", \"enum\": [\"red\", \"blue\"]\n mode: Literal[\"fast\", \"slow\"], # -> \"type\": \"string\", \"enum\": [\"fast\", \"slow\"]\n) -> None: ...\n```\n\n### Optional and Union Types\n```python\ndef func(\n opt1: str | None, # -> \"type\": \"string\"\n opt2: int | None, # -> \"type\": \"integer\"\n union: str | int, # -> \"type\": \"string\" (first type)\n) -> None: ...\n```\n\n### Custom Types\n```python\n@dataclass\nclass User:\n name: str\n age: int\n\ndef func(\n user: User, # -> \"type\": \"object\"\n data: JsonDict, # -> \"type\": \"object\"\n) -> None: ...\n```\n\n### Type Aliases\n```python\nJsonValue = dict[str, Any] | list[Any] | str | int | float | bool | None\nJsonDict = dict[str, JsonValue]\n\ndef func(\n data: JsonDict, # -> \"type\": \"object\"\n values: list[JsonValue], # -> \"type\": \"array\"\n) -> None: ...\n```\n\n### Recursive Types\n```python\ndef func(\n tree: dict[str, \"dict[str, Any] | str\"], # -> \"type\": \"object\"\n nested: dict[str, list[\"dict[str, Any]\"]], # -> \"type\": \"object\"\n) -> None: ...\n```\n\n## Generated Schema Example\n\n```python\n{\n \"type\": \"function\",\n \"function\": {\n \"name\": \"get_weather\",\n \"description\": \"Get the weather for a location.\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"location\": {\n \"type\": \"string\",\n \"description\": \"City or address to get weather for\"\n },\n \"unit\": {\n \"type\": \"string\",\n \"enum\": [\"C\", \"F\"],\n \"description\": \"Temperature unit (Celsius or Fahrenheit)\",\n \"default\": \"C\"\n },\n \"detailed\": {\n \"type\": \"boolean\",\n \"description\": \"Include extended forecast\",\n \"default\": false\n }\n },\n \"required\": [\"location\"]\n }\n }\n}\n```\n\n## Schema Generators\n\n### Module Schemas\n\nYou can generate schemas for all public functions in a module using `create_schemas_from_module`:\n\n```python\nfrom py2openai import create_schemas_from_module\nimport math\n\n# Generate schemas for all public functions\nschemas = create_schemas_from_module(math)\n\n# Generate schemas for specific functions only\nschemas = create_schemas_from_module(math, include_functions=['sin', 'cos'])\n\n# Import module by string name\nschemas = create_schemas_from_module('math')\n```\n\n### Class Schemas\n\nGenerate schemas for all public methods in a class using `create_schemas_from_class`:\n\n```python\nfrom py2openai import create_schemas_from_class\n\nclass Calculator:\n def add(self, x: int, y: int) -> int:\n \"\"\"Add two numbers.\n\n Args:\n x: First number\n y: Second number\n\n Returns:\n Sum of x and y\n \"\"\"\n return x + y\n\n @classmethod\n def multiply(cls, x: int, y: int) -> int:\n \"\"\"Multiply two numbers.\n\n Args:\n x: First number\n y: Second number\n\n Returns:\n Product of x and y\n \"\"\"\n return x * y\n\n @staticmethod\n def divide(x: float, y: float) -> float:\n \"\"\"Divide two numbers.\n\n Args:\n x: Numerator\n y: Denominator\n\n Returns:\n Result of x divided by y\n \"\"\"\n return x / y\n\n# Generate schemas for all public methods\nschemas = create_schemas_from_class(Calculator)\n\n# Access individual method schemas\nadd_schema = schemas['Calculator.add']\nmultiply_schema = schemas['Calculator.multiply']\ndivide_schema = schemas['Calculator.divide']\n```\n\nThe schema generators support:\n\n- Regular functions\n- Regular instance methods (bound and unbound)\n- Class methods\n- Static methods\n- Decorated functions / methods\n- Async functions / methods\n- Property methods\n- Basically all stdlib typing features as well as many stdlib types\n- Method docstrings for descriptions\n- Default values\n- Return type hints\n\n\n## Diferences to pydantic schema generation\n\nWhile Pydantics schema generation preserves detailed type information, `schema.model_dump_openai()`\nsimplifies types to match OpenAI's function calling format. Most special types\n(datetime, UUID, Path, etc.) are handled similarly by both (we only strip unused information), but we handle enums\ndifferently: Instead of preserving enum class information, we extract just the values\nas a string enum. Union types and Optionals are also handled differently - we typically\npick the first type to keep the schema simple and practical for AI interaction.\nThis ensures compatibility with OpenAI's function calling API while maintaining enough\ntype information for the AI to understand the function signature.\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2024, Philipp Temminghoff\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n ",
"summary": "Create OpenAI-compatible function schemas from python functions",
"version": "0.10.0",
"project_urls": {
"Code coverage": "https://app.codecov.io/gh/phil65/py2openai",
"Discussions": "https://github.com/phil65/py2openai/discussions",
"Documentation": "https://phil65.github.io/py2openai/",
"Issues": "https://github.com/phil65/py2openai/issues",
"Source": "https://github.com/phil65/py2openai"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "6e4aef2c04381f31331b32706b20281d12c271169b615e756e5738550f10d256",
"md5": "32ce684d0bf2c6bb46a928b1256e9c21",
"sha256": "41af24070a6f70bc83b582d7a5c9cbf1139cef6db4e4f3e022e2438b4f48143e"
},
"downloads": -1,
"filename": "py2openai-0.10.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "32ce684d0bf2c6bb46a928b1256e9c21",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 23300,
"upload_time": "2025-10-06T20:26:40",
"upload_time_iso_8601": "2025-10-06T20:26:40.061382Z",
"url": "https://files.pythonhosted.org/packages/6e/4a/ef2c04381f31331b32706b20281d12c271169b615e756e5738550f10d256/py2openai-0.10.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e9b5a3a88aae1012cc817857f5dc248745e6947ccc63f2097f8048af837077f1",
"md5": "53a812bf252904712220729df1052809",
"sha256": "f831f64422f782ca867bbfe4a0ca08fb65c3b100723f3855e25d8094dc78fad6"
},
"downloads": -1,
"filename": "py2openai-0.10.0.tar.gz",
"has_sig": false,
"md5_digest": "53a812bf252904712220729df1052809",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 21806,
"upload_time": "2025-10-06T20:26:41",
"upload_time_iso_8601": "2025-10-06T20:26:41.475140Z",
"url": "https://files.pythonhosted.org/packages/e9/b5/a3a88aae1012cc817857f5dc248745e6947ccc63f2097f8048af837077f1/py2openai-0.10.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 20:26:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "phil65",
"github_project": "py2openai",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "py2openai"
}