Skip to content

Commit 858c7fc

Browse files
committed
Fix Python cookbook recipes to use correct async SDK API
All 5 Python recipes and their markdown docs used a synchronous, kwargs-based API that doesn't match the real github-copilot-sdk: - client.start() -> await client.start() (all methods are async) - create_session(model=...) -> create_session(SessionConfig(model=...)) - session.send(prompt=...) -> session.send(MessageOptions(prompt=...)) - session.wait_for_idle() -> session.send_and_wait() (wait_for_idle doesn't exist) - event['type']/event['data']['content'] -> event.type/event.data.content - All code wrapped in async def main() + asyncio.run(main()) Verified all imports resolve against github-copilot-sdk.
1 parent 4555fee commit 858c7fc

File tree

10 files changed

+283
-303
lines changed

10 files changed

+283
-303
lines changed

cookbook/copilot-sdk/python/error-handling.md

Lines changed: 32 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,35 @@ You need to handle various error conditions like connection failures, timeouts,
1616
## Basic try-except
1717
1818
```python
19-
from copilot import CopilotClient
19+
import asyncio
20+
from copilot import CopilotClient, SessionConfig, MessageOptions
2021
21-
client = CopilotClient()
22+
async def main():
23+
client = CopilotClient()
2224
23-
try:
24-
client.start()
25-
session = client.create_session(model="gpt-5")
25+
try:
26+
await client.start()
27+
session = await client.create_session(SessionConfig(model="gpt-5"))
2628
27-
response = None
28-
def handle_message(event):
29-
nonlocal response
30-
if event["type"] == "assistant.message":
31-
response = event["data"]["content"]
29+
response = await session.send_and_wait(MessageOptions(prompt="Hello!"))
3230
33-
session.on(handle_message)
34-
session.send(prompt="Hello!")
35-
session.wait_for_idle()
31+
if response:
32+
print(response.data.content)
3633
37-
if response:
38-
print(response)
34+
await session.destroy()
35+
except Exception as e:
36+
print(f"Error: {e}")
37+
finally:
38+
await client.stop()
3939
40-
session.destroy()
41-
except Exception as e:
42-
print(f"Error: {e}")
43-
finally:
44-
client.stop()
40+
asyncio.run(main())
4541
```
4642
4743
## Handling specific error types
4844
4945
```python
50-
import subprocess
51-
5246
try:
53-
client.start()
47+
await client.start()
5448
except FileNotFoundError:
5549
print("Copilot CLI not found. Please install it first.")
5650
except ConnectionError:
@@ -62,31 +56,14 @@ except Exception as e:
6256
## Timeout handling
6357
6458
```python
65-
import signal
66-
from contextlib import contextmanager
67-
68-
@contextmanager
69-
def timeout(seconds):
70-
def timeout_handler(signum, frame):
71-
raise TimeoutError("Request timed out")
72-
73-
old_handler = signal.signal(signal.SIGALRM, timeout_handler)
74-
signal.alarm(seconds)
75-
try:
76-
yield
77-
finally:
78-
signal.alarm(0)
79-
signal.signal(signal.SIGALRM, old_handler)
80-
81-
session = client.create_session(model="gpt-5")
59+
session = await client.create_session(SessionConfig(model="gpt-5"))
8260
8361
try:
84-
session.send(prompt="Complex question...")
85-
86-
# Wait with timeout (30 seconds)
87-
with timeout(30):
88-
session.wait_for_idle()
89-
62+
# send_and_wait accepts an optional timeout in seconds
63+
response = await session.send_and_wait(
64+
MessageOptions(prompt="Complex question..."),
65+
timeout=30.0
66+
)
9067
print("Response received")
9168
except TimeoutError:
9269
print("Request timed out")
@@ -95,21 +72,15 @@ except TimeoutError:
9572
## Aborting a request
9673
9774
```python
98-
import threading
99-
100-
session = client.create_session(model="gpt-5")
75+
session = await client.create_session(SessionConfig(model="gpt-5"))
10176
102-
# Start a request
103-
session.send(prompt="Write a very long story...")
77+
# Start a request (non-blocking send)
78+
await session.send(MessageOptions(prompt="Write a very long story..."))
10479
10580
# Abort it after some condition
106-
def abort_later():
107-
import time
108-
time.sleep(5)
109-
session.abort()
110-
print("Request aborted")
111-
112-
threading.Thread(target=abort_later).start()
81+
await asyncio.sleep(5)
82+
await session.abort()
83+
print("Request aborted")
11384
```
11485
11586
## Graceful shutdown
@@ -120,31 +91,15 @@ import sys
12091
12192
def signal_handler(sig, frame):
12293
print("\nShutting down...")
123-
errors = client.stop()
124-
if errors:
125-
print(f"Cleanup errors: {errors}")
94+
asyncio.get_event_loop().run_until_complete(client.stop())
12695
sys.exit(0)
12796
12897
signal.signal(signal.SIGINT, signal_handler)
12998
```
13099
131-
## Context manager for automatic cleanup
132-
133-
```python
134-
from copilot import CopilotClient
135-
136-
with CopilotClient() as client:
137-
client.start()
138-
session = client.create_session(model="gpt-5")
139-
140-
# ... do work ...
141-
142-
# client.stop() is automatically called when exiting context
143-
```
144-
145100
## Best practices
146101
147-
1. **Always clean up**: Use try-finally or context managers to ensure `stop()` is called
102+
1. **Always clean up**: Use try-finally to ensure `await client.stop()` is called
148103
2. **Handle connection errors**: The CLI might not be installed or running
149-
3. **Set appropriate timeouts**: Long-running requests should have timeouts
104+
3. **Set appropriate timeouts**: Use the `timeout` parameter on `send_and_wait()`
150105
4. **Log errors**: Capture error details for debugging

cookbook/copilot-sdk/python/managing-local-files.md

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,36 @@ You have a folder with many files and want to organize them into subfolders base
1616
## Example code
1717
1818
```python
19-
from copilot import CopilotClient
19+
import asyncio
2020
import os
21-
22-
# Create and start client
23-
client = CopilotClient()
24-
client.start()
25-
26-
# Create session
27-
session = client.create_session(model="gpt-5")
28-
29-
# Event handler
30-
def handle_event(event):
31-
if event["type"] == "assistant.message":
32-
print(f"\nCopilot: {event['data']['content']}")
33-
elif event["type"] == "tool.execution_start":
34-
print(f" → Running: {event['data']['toolName']}")
35-
elif event["type"] == "tool.execution_complete":
36-
print(f" ✓ Completed: {event['data']['toolCallId']}")
37-
38-
session.on(handle_event)
39-
40-
# Ask Copilot to organize files
41-
target_folder = os.path.expanduser("~/Downloads")
42-
43-
session.send(prompt=f"""
21+
from copilot import (
22+
CopilotClient, SessionConfig, MessageOptions,
23+
SessionEvent, SessionEventType,
24+
)
25+
26+
async def main():
27+
# Create and start client
28+
client = CopilotClient()
29+
await client.start()
30+
31+
# Create session
32+
session = await client.create_session(SessionConfig(model="gpt-5"))
33+
34+
# Event handler
35+
def handle_event(event: SessionEvent):
36+
if event.type == SessionEventType.ASSISTANT_MESSAGE:
37+
print(f"\nCopilot: {event.data.content}")
38+
elif event.type == SessionEventType.TOOL_EXECUTION_START:
39+
print(f" → Running: {event.data.tool_name}")
40+
elif event.type == SessionEventType.TOOL_EXECUTION_COMPLETE:
41+
print(f" ✓ Completed: {event.data.tool_call_id}")
42+
43+
session.on(handle_event)
44+
45+
# Ask Copilot to organize files
46+
target_folder = os.path.expanduser("~/Downloads")
47+
48+
await session.send_and_wait(MessageOptions(prompt=f"""
4449
Analyze the files in "{target_folder}" and organize them into subfolders.
4550
4651
1. First, list all files and their metadata
@@ -49,11 +54,12 @@ Analyze the files in "{target_folder}" and organize them into subfolders.
4954
4. Move each file to its appropriate subfolder
5055
5156
Please confirm before moving any files.
52-
""")
57+
"""))
5358
54-
session.wait_for_idle()
59+
await session.destroy()
60+
await client.stop()
5561
56-
client.stop()
62+
asyncio.run(main())
5763
```
5864
5965
## Grouping strategies
@@ -90,26 +96,26 @@ client.stop()
9096
For safety, you can ask Copilot to only preview changes:
9197
9298
```python
93-
session.send(prompt=f"""
99+
await session.send_and_wait(MessageOptions(prompt=f"""
94100
Analyze files in "{target_folder}" and show me how you would organize them
95101
by file type. DO NOT move any files - just show me the plan.
96-
""")
102+
"""))
97103
```
98104
99105
## Custom grouping with AI analysis
100106
101107
Let Copilot determine the best grouping based on file content:
102108
103109
```python
104-
session.send(prompt=f"""
110+
await session.send_and_wait(MessageOptions(prompt=f"""
105111
Look at the files in "{target_folder}" and suggest a logical organization.
106112
Consider:
107113
- File names and what they might contain
108114
- File types and their typical uses
109115
- Date patterns that might indicate projects or events
110116
111117
Propose folder names that are descriptive and useful.
112-
""")
118+
"""))
113119
```
114120
115121
## Safety considerations

cookbook/copilot-sdk/python/multiple-sessions.md

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,59 +16,63 @@ You need to run multiple conversations in parallel, each with its own context an
1616
## Python
1717
1818
```python
19-
from copilot import CopilotClient
20-
21-
client = CopilotClient()
22-
client.start()
23-
24-
# Create multiple independent sessions
25-
session1 = client.create_session(model="gpt-5")
26-
session2 = client.create_session(model="gpt-5")
27-
session3 = client.create_session(model="claude-sonnet-4.5")
28-
29-
# Each session maintains its own conversation history
30-
session1.send(prompt="You are helping with a Python project")
31-
session2.send(prompt="You are helping with a TypeScript project")
32-
session3.send(prompt="You are helping with a Go project")
33-
34-
# Follow-up messages stay in their respective contexts
35-
session1.send(prompt="How do I create a virtual environment?")
36-
session2.send(prompt="How do I set up tsconfig?")
37-
session3.send(prompt="How do I initialize a module?")
38-
39-
# Clean up all sessions
40-
session1.destroy()
41-
session2.destroy()
42-
session3.destroy()
43-
client.stop()
19+
import asyncio
20+
from copilot import CopilotClient, SessionConfig, MessageOptions
21+
22+
async def main():
23+
client = CopilotClient()
24+
await client.start()
25+
26+
# Create multiple independent sessions
27+
session1 = await client.create_session(SessionConfig(model="gpt-5"))
28+
session2 = await client.create_session(SessionConfig(model="gpt-5"))
29+
session3 = await client.create_session(SessionConfig(model="claude-sonnet-4.5"))
30+
31+
# Each session maintains its own conversation history
32+
await session1.send_and_wait(MessageOptions(prompt="You are helping with a Python project"))
33+
await session2.send_and_wait(MessageOptions(prompt="You are helping with a TypeScript project"))
34+
await session3.send_and_wait(MessageOptions(prompt="You are helping with a Go project"))
35+
36+
# Follow-up messages stay in their respective contexts
37+
await session1.send_and_wait(MessageOptions(prompt="How do I create a virtual environment?"))
38+
await session2.send_and_wait(MessageOptions(prompt="How do I set up tsconfig?"))
39+
await session3.send_and_wait(MessageOptions(prompt="How do I initialize a module?"))
40+
41+
# Clean up all sessions
42+
await session1.destroy()
43+
await session2.destroy()
44+
await session3.destroy()
45+
await client.stop()
46+
47+
asyncio.run(main())
4448
```
4549
4650
## Custom session IDs
4751

4852
Use custom IDs for easier tracking:
4953

5054
```python
51-
session = client.create_session(
55+
session = await client.create_session(SessionConfig(
5256
session_id="user-123-chat",
5357
model="gpt-5"
54-
)
58+
))
5559

5660
print(session.session_id) # "user-123-chat"
5761
```
5862

5963
## Listing sessions
6064

6165
```python
62-
sessions = client.list_sessions()
66+
sessions = await client.list_sessions()
6367
for session_info in sessions:
64-
print(f"Session: {session_info['sessionId']}")
68+
print(f"Session: {session_info.session_id}")
6569
```
6670

6771
## Deleting sessions
6872

6973
```python
7074
# Delete a specific session
71-
client.delete_session("user-123-chat")
75+
await client.delete_session("user-123-chat")
7276
```
7377

7478
## Use cases

0 commit comments

Comments
 (0)