Skip to content

Commit 994aa9d

Browse files
authored
Merge pull request #23 from comfuture/copilot/fix-22
Separate example codes from README and add OpenAI, Claude, MCP examples
2 parents 78e48bd + da1782c commit 994aa9d

File tree

10 files changed

+947
-93
lines changed

10 files changed

+947
-93
lines changed

README.md

Lines changed: 13 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Will output:
7777
}
7878
```
7979

80-
for claude, you should pass 2nd argument as SchemaFormat.claude or `claude`:
80+
For claude, you should pass 2nd argument as SchemaFormat.claude or `claude`:
8181

8282
```python
8383
from function_schema import get_function_schema
@@ -90,114 +90,35 @@ Please refer to the [Claude tool use](https://docs.anthropic.com/claude/docs/too
9090
You can use any type hinting supported by python for the first argument of `Annotated`. including:
9191
`typing.Literal`, `typing.Optional`, `typing.Union`, and `T | None` for python 3.10+.
9292
`Doc` class or plain string in `Annotated` is used for describe the parameter.
93-
`Doc` metadata is the [PEP propose](https://peps.python.org/pep-0727/) for standardizing the metadata in type hints.
94-
currently, implemented in `typing-extensions` module. Also `function_schema.Doc` is provided for compatibility.
9593

9694
Enumeratable candidates can be defined with `enum.Enum` in the argument of `Annotated`.
95+
In shorthand, you can use `typing.Literal` as the type will do the same thing:
9796

9897
```python
99-
import enum
100-
101-
class AnimalType(enum.Enum):
102-
dog = enum.auto()
103-
cat = enum.auto()
104-
105-
def get_animal(
106-
animal: Annotated[str, Doc("The animal to get"), AnimalType],
107-
) -> str:
108-
"""Returns the animal."""
109-
return f"Animal is {animal.value}"
110-
```
111-
In this example, each name of `AnimalType` enums(`dog`, `cat`) is used as an enum schema.
112-
In shorthand, you can use `typing.Literal` as the type will do the same thing.
98+
from typing import Annotated, Literal
11399

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

122-
123-
### Plain String in Annotated
124-
125-
The string value of `Annotated` is used as a description for convenience.
126-
127-
```python
128-
def get_weather(
129-
city: Annotated[str, "The city to get the weather for"], # <- string value of Annotated is used as a description
130-
unit: Annotated[Optional[str], "The unit to return the temperature in"] = "celcius",
131-
) -> str:
132-
"""Returns the weather for the given city."""
133-
return f"Weather for {city} is 20°C"
134-
```
135-
136-
But this would create a predefined meaning for any plain string inside of `Annotated`,
137-
and any tool that was using plain strings in them for any other purpose, which is currently allowed, would now be invalid.
138-
Please refer to the [PEP 0727, Plain String in Annotated](https://peps.python.org/pep-0727/#plain-string-in-annotated) for more information.
139-
140-
### Usage with OpenAI API
141-
142-
You can use this schema to make a function call in OpenAI API:
143-
```python
144-
import openai
145-
openai.api_key = "sk-..."
146-
147-
# Create an assistant with the function
148-
assistant = client.beta.assistants.create(
149-
instructions="You are a weather bot. Use the provided functions to answer questions.",
150-
model="gpt-4-turbo-preview",
151-
tools=[{
152-
"type": "function",
153-
"function": get_function_schema(get_weather),
154-
}]
155-
)
156-
157-
run = client.beta.messages.create(
158-
assistant_id=assistant.id,
159-
messages=[
160-
{"role": "user", "content": "What's the weather like in Seoul?"}
161-
]
162-
)
163-
164-
# or with chat completion
165-
166-
result = openai.chat.completion.create(
167-
model="gpt-3.5-turbo",
168-
messages=[
169-
{"role": "user", "content": "What's the weather like in Seoul?"}
170-
],
171-
tools=[{
172-
"type": "function",
173-
"function": get_function_schema(get_weather)
174-
}],
175-
tool_call="auto",
176-
)
177-
```
178-
179-
### Usage with Anthropic Claude
180-
181-
```python
182-
import anthropic
183-
184-
client = anthropic.Client()
185-
186-
response = client.beta.tools.messages.create(
187-
model="claude-3-opus-20240229",
188-
max_tokens=4096,
189-
tools=[get_function_schema(get_weather, "claude")],
190-
messages=[
191-
{"role": "user", "content": "What's the weather like in Seoul?"}
192-
]
193-
)
194-
```
195-
196107
### CLI usage
197108

198109
```sh
199110
function_schema mymodule.py my_function | jq
200111
```
201112

113+
### More Examples
114+
115+
For comprehensive usage examples with different AI platforms, see the [examples directory](./examples/):
116+
117+
- **[Basic Usage](./examples/basic_usage.py)** - Core features and function definition patterns
118+
- **[OpenAI Integration](./examples/openai_example.py)** - Assistant API and Chat Completion examples
119+
- **[Claude Integration](./examples/claude_example.py)** - Anthropic Claude tool calling examples
120+
- **[MCP Integration](./examples/mcp_example.py)** - Model Context Protocol examples
121+
- **[CLI Usage](./examples/cli_example.py)** - Command-line interface examples
122+
202123
## License
203124
MIT License

examples/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Function Schema Examples
2+
3+
This directory contains practical examples of how to use the `function-schema` library with various AI platforms and protocols.
4+
5+
## Examples
6+
7+
### 🔧 Basic Usage (`basic_usage.py`)
8+
Demonstrates the fundamental features of function-schema:
9+
- Creating functions with type annotations and Doc metadata
10+
- Generating JSON schemas
11+
- Using enums and Literal types for parameter constraints
12+
- Different annotation styles
13+
14+
**Run:** `python examples/basic_usage.py`
15+
16+
### 🤖 OpenAI Integration (`openai_example.py`)
17+
Shows how to integrate with OpenAI's APIs:
18+
- Assistant API with tool calling
19+
- Chat Completion API with function calling
20+
- Multiple tool definitions
21+
22+
**Run:** `python examples/openai_example.py`
23+
24+
### 🧠 Claude Integration (`claude_example.py`)
25+
Demonstrates Anthropic Claude tool calling:
26+
- Basic tool calling setup
27+
- Multi-turn conversations with tools
28+
- Claude-specific schema format
29+
30+
**Run:** `python examples/claude_example.py`
31+
32+
### 📟 CLI Usage (`cli_example.py`)
33+
Examples of using the command-line interface:
34+
- Generating schemas from Python files
35+
- Different output formats
36+
- Working with multiple functions
37+
38+
**Test the CLI:**
39+
```bash
40+
# Install the package first
41+
pip install -e .
42+
43+
# Generate schema for a function
44+
function_schema examples/cli_example.py get_weather
45+
46+
# Generate with pretty JSON formatting
47+
function_schema examples/cli_example.py get_weather | jq
48+
49+
# Generate for Claude format
50+
function_schema examples/cli_example.py get_weather claude
51+
```
52+
53+
### 🔌 MCP Integration (`mcp_example.py`)
54+
Shows integration with Model Context Protocol:
55+
- Creating MCP-compatible tool definitions
56+
- Server manifest generation
57+
- Tool calling examples
58+
- Resource access patterns
59+
60+
**Run:** `python examples/mcp_example.py`
61+
62+
## Running the Examples
63+
64+
1. **Install the package:**
65+
```bash
66+
pip install -e .
67+
```
68+
69+
2. **Run any example:**
70+
```bash
71+
python examples/basic_usage.py
72+
python examples/openai_example.py
73+
python examples/claude_example.py
74+
python examples/mcp_example.py
75+
```
76+
77+
3. **Test CLI functionality:**
78+
```bash
79+
function_schema examples/cli_example.py get_weather
80+
```
81+
82+
## Integration Notes
83+
84+
- **OpenAI**: Requires `openai` library and API key for actual usage
85+
- **Claude**: Requires `anthropic` library and API key for actual usage
86+
- **MCP**: Conceptual example showing schema compatibility
87+
- **CLI**: Works out of the box with the installed package
88+
89+
## Schema Formats
90+
91+
The library supports multiple output formats:
92+
- **OpenAI format** (default): Uses `parameters` key
93+
- **Claude format**: Uses `input_schema` key
94+
95+
Specify format with: `get_function_schema(func, "claude")`

examples/basic_usage.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"""
2+
Basic usage example for function-schema library.
3+
4+
This example demonstrates how to:
5+
1. Define a function with type annotations and Doc metadata
6+
2. Generate a JSON schema from the function
7+
3. Use enum for parameter constraints
8+
"""
9+
10+
from typing import Annotated, Optional, Literal
11+
from function_schema import Doc, get_function_schema
12+
import enum
13+
import json
14+
15+
16+
def get_weather(
17+
city: Annotated[str, Doc("The city to get the weather for")],
18+
unit: Annotated[
19+
Optional[str],
20+
Doc("The unit to return the temperature in"),
21+
enum.Enum("Unit", "celcius fahrenheit")
22+
] = "celcius",
23+
) -> str:
24+
"""Returns the weather for the given city."""
25+
return f"Weather for {city} is 20°C"
26+
27+
28+
def get_animal_with_enum(
29+
animal: Annotated[str, Doc("The animal to get"),
30+
enum.Enum("AnimalType", "dog cat")],
31+
) -> str:
32+
"""Returns the animal using enum."""
33+
return f"Animal is {animal}"
34+
35+
36+
class AnimalType(enum.Enum):
37+
dog = enum.auto()
38+
cat = enum.auto()
39+
40+
41+
def get_animal_with_class_enum(
42+
animal: Annotated[str, Doc("The animal to get"), AnimalType],
43+
) -> str:
44+
"""Returns the animal using class-based enum."""
45+
return f"Animal is {animal.value}"
46+
47+
48+
def get_animal_with_literal(
49+
animal: Annotated[Literal["dog", "cat"], Doc("The animal to get")],
50+
) -> str:
51+
"""Returns the animal using Literal type."""
52+
return f"Animal is {animal}"
53+
54+
55+
def get_weather_with_string_annotation(
56+
city: Annotated[str, "The city to get the weather for"],
57+
unit: Annotated[Optional[str], "The unit to return the temperature in"] = "celcius",
58+
) -> str:
59+
"""Returns the weather for the given city using plain string annotations."""
60+
return f"Weather for {city} is 20°C"
61+
62+
63+
if __name__ == "__main__":
64+
# Generate schema for the main weather function
65+
schema = get_function_schema(get_weather)
66+
print("Basic weather function schema:")
67+
print(json.dumps(schema, indent=2))
68+
69+
print("\n" + "="*50 + "\n")
70+
71+
# Generate schema for Claude format
72+
claude_schema = get_function_schema(get_weather, "claude")
73+
print("Schema for Claude:")
74+
print(json.dumps(claude_schema, indent=2))
75+
76+
print("\n" + "="*50 + "\n")
77+
78+
# Generate schema for enum example
79+
enum_schema = get_function_schema(get_animal_with_enum)
80+
print("Animal enum schema:")
81+
print(json.dumps(enum_schema, indent=2))
82+
83+
print("\n" + "="*50 + "\n")
84+
85+
# Generate schema for Literal example
86+
literal_schema = get_function_schema(get_animal_with_literal)
87+
print("Animal literal schema:")
88+
print(json.dumps(literal_schema, indent=2))

0 commit comments

Comments
 (0)