Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 32 additions & 164 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,186 +18,54 @@ pip install function-schema

## Usage

```python
from typing import Annotated, Optional
from function_schema import Doc
import enum

def get_weather(
city: Annotated[str, Doc("The city to get the weather for")],
unit: Annotated[
Optional[str],
Doc("The unit to return the temperature in"),
enum.Enum("Unit", "celcius fahrenheit")
] = "celcius",
) -> str:
"""Returns the weather for the given city."""
return f"Weather for {city} is 20°C"
```

Function description is taken from the docstring.
Type hinting with `typing.Annotated` for annotate additional information about the parameters and return type.

Then you can generate a schema for this function:
```python
import json
from function_schema import get_function_schema

schema = get_function_schema(get_weather)
print(json.dumps(schema, indent=2))
```

Will output:

```json
{
"name": "get_weather",
"description": "Returns the weather for the given city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city to get the weather for"
},
"unit": {
"type": "string",
"description": "The unit to return the temperature in",
"enum": [
"celcius",
"fahrenheit"
],
"default": "celcius"
}
},
}
"required": [
"city"
]
}
```

for claude, you should pass 2nd argument as SchemaFormat.claude or `claude`:

```python
from function_schema import get_function_schema

schema = get_function_schema(get_weather, "claude")
```

Please refer to the [Claude tool use](https://docs.anthropic.com/claude/docs/tool-use) documentation for more information.
See the [examples directory](./examples/) for comprehensive usage examples with different AI platforms:
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to leave the most basic usage instructions in the readme.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added basic usage instructions back to the README. The main usage section now shows the complete flow from function definition to schema generation with example output, addressing the feedback to keep essential instructions in the README itself. Commit 482f667.


You can use any type hinting supported by python for the first argument of `Annotated`. including:
`typing.Literal`, `typing.Optional`, `typing.Union`, and `T | None` for python 3.10+.
`Doc` class or plain string in `Annotated` is used for describe the parameter.
`Doc` metadata is the [PEP propose](https://peps.python.org/pep-0727/) for standardizing the metadata in type hints.
currently, implemented in `typing-extensions` module. Also `function_schema.Doc` is provided for compatibility.
- **[Basic Usage](./examples/basic_usage.py)** - Core features and function definition patterns
- **[OpenAI Integration](./examples/openai_example.py)** - Assistant API and Chat Completion examples
- **[Claude Integration](./examples/claude_example.py)** - Anthropic Claude tool calling examples
- **[MCP Integration](./examples/mcp_example.py)** - Model Context Protocol examples
- **[CLI Usage](./examples/cli_example.py)** - Command-line interface examples

Enumeratable candidates can be defined with `enum.Enum` in the argument of `Annotated`.
### Quick Start

```python
import enum
from typing import Annotated
from function_schema import Doc, get_function_schema

class AnimalType(enum.Enum):
dog = enum.auto()
cat = enum.auto()

def get_animal(
animal: Annotated[str, Doc("The animal to get"), AnimalType],
) -> str:
"""Returns the animal."""
return f"Animal is {animal.value}"
```
In this example, each name of `AnimalType` enums(`dog`, `cat`) is used as an enum schema.
In shorthand, you can use `typing.Literal` as the type will do the same thing.

```python
def get_animal(
animal: Annotated[Literal["dog", "cat"], Doc("The animal to get")],
) -> str:
"""Returns the animal."""
return f"Animal is {animal}"
```


### Plain String in Annotated

The string value of `Annotated` is used as a description for convenience.

```python
def get_weather(
city: Annotated[str, "The city to get the weather for"], # <- string value of Annotated is used as a description
unit: Annotated[Optional[str], "The unit to return the temperature in"] = "celcius",
) -> str:
def get_weather(city: Annotated[str, Doc("The city to get the weather for")]) -> str:
"""Returns the weather for the given city."""
return f"Weather for {city} is 20°C"

# Generate schema
schema = get_function_schema(get_weather)
```

But this would create a predefined meaning for any plain string inside of `Annotated`,
and any tool that was using plain strings in them for any other purpose, which is currently allowed, would now be invalid.
Please refer to the [PEP 0727, Plain String in Annotated](https://peps.python.org/pep-0727/#plain-string-in-annotated) for more information.
### Key Features

### Usage with OpenAI API
- **Type Annotations**: Use `typing.Annotated` with `Doc` metadata for parameter descriptions
- **Multiple Formats**: Support for OpenAI (`"openai"`) and Claude (`"claude"`) schema formats
- **Enum Support**: Use `enum.Enum` or `typing.Literal` for parameter constraints
- **CLI Tool**: Generate schemas from command line using `function_schema`

You can use this schema to make a function call in OpenAI API:
```python
import openai
openai.api_key = "sk-..."

# Create an assistant with the function
assistant = client.beta.assistants.create(
instructions="You are a weather bot. Use the provided functions to answer questions.",
model="gpt-4-turbo-preview",
tools=[{
"type": "function",
"function": get_function_schema(get_weather),
}]
)

run = client.beta.messages.create(
assistant_id=assistant.id,
messages=[
{"role": "user", "content": "What's the weather like in Seoul?"}
]
)

# or with chat completion

result = openai.chat.completion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "What's the weather like in Seoul?"}
],
tools=[{
"type": "function",
"function": get_function_schema(get_weather)
}],
tool_call="auto",
)
```
For detailed examples and advanced usage patterns, see the [examples directory](./examples/).

### Usage with Anthropic Claude
### Platform Integration

```python
import anthropic

client = anthropic.Client()

response = client.beta.tools.messages.create(
model="claude-3-opus-20240229",
max_tokens=4096,
tools=[get_function_schema(get_weather, "claude")],
messages=[
{"role": "user", "content": "What's the weather like in Seoul?"}
]
)
```
#### OpenAI API
For detailed OpenAI integration examples including Assistant API and Chat Completion, see [examples/openai_example.py](./examples/openai_example.py).

### CLI usage
#### Anthropic Claude
For Claude tool calling examples and multi-turn conversations, see [examples/claude_example.py](./examples/claude_example.py).

```sh
function_schema mymodule.py my_function | jq
#### Model Context Protocol (MCP)
For MCP server and tool integration examples, see [examples/mcp_example.py](./examples/mcp_example.py).

#### CLI Usage
Generate schemas from command line:
```bash
function_schema examples/cli_example.py get_weather | jq
```
For more CLI examples, see [examples/cli_example.py](./examples/cli_example.py).

## License
MIT License
95 changes: 95 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Function Schema Examples

This directory contains practical examples of how to use the `function-schema` library with various AI platforms and protocols.

## Examples

### 🔧 Basic Usage (`basic_usage.py`)
Demonstrates the fundamental features of function-schema:
- Creating functions with type annotations and Doc metadata
- Generating JSON schemas
- Using enums and Literal types for parameter constraints
- Different annotation styles

**Run:** `python examples/basic_usage.py`

### 🤖 OpenAI Integration (`openai_example.py`)
Shows how to integrate with OpenAI's APIs:
- Assistant API with tool calling
- Chat Completion API with function calling
- Multiple tool definitions

**Run:** `python examples/openai_example.py`

### 🧠 Claude Integration (`claude_example.py`)
Demonstrates Anthropic Claude tool calling:
- Basic tool calling setup
- Multi-turn conversations with tools
- Claude-specific schema format

**Run:** `python examples/claude_example.py`

### 📟 CLI Usage (`cli_example.py`)
Examples of using the command-line interface:
- Generating schemas from Python files
- Different output formats
- Working with multiple functions

**Test the CLI:**
```bash
# Install the package first
pip install -e .

# Generate schema for a function
function_schema examples/cli_example.py get_weather

# Generate with pretty JSON formatting
function_schema examples/cli_example.py get_weather | jq

# Generate for Claude format
function_schema examples/cli_example.py get_weather claude
```

### 🔌 MCP Integration (`mcp_example.py`)
Shows integration with Model Context Protocol:
- Creating MCP-compatible tool definitions
- Server manifest generation
- Tool calling examples
- Resource access patterns

**Run:** `python examples/mcp_example.py`

## Running the Examples

1. **Install the package:**
```bash
pip install -e .
```

2. **Run any example:**
```bash
python examples/basic_usage.py
python examples/openai_example.py
python examples/claude_example.py
python examples/mcp_example.py
```

3. **Test CLI functionality:**
```bash
function_schema examples/cli_example.py get_weather
```

## Integration Notes

- **OpenAI**: Requires `openai` library and API key for actual usage
- **Claude**: Requires `anthropic` library and API key for actual usage
- **MCP**: Conceptual example showing schema compatibility
- **CLI**: Works out of the box with the installed package

## Schema Formats

The library supports multiple output formats:
- **OpenAI format** (default): Uses `parameters` key
- **Claude format**: Uses `input_schema` key

Specify format with: `get_function_schema(func, "claude")`
Loading