1- # hawk-sdk
2-
3- Python SDK for the [ Hawk] ( https://github.com/hawk-eco/hawk ) daemon API.
1+ <p align =" center " >
2+ <h1 align =" center " >Hawk SDK for Python</h1 >
3+ <p align =" center " >
4+ <strong>Official Python client for the Hawk daemon API</strong>
5+ </p >
6+ <p align =" center " >
7+ <a href="https://python.org/"><img src="https://img.shields.io/badge/Python-3.10+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python"></a>
8+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
9+ <a href="https://github.com/GrayCodeAI/hawk-sdk-python/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/GrayCodeAI/hawk-sdk-python/ci.yml?style=flat-square&label=tests" alt="CI"></a>
10+ </p >
11+ </p >
12+
13+ ---
14+
15+ The Hawk SDK for Python provides an idiomatic client for interacting with the [ Hawk] ( https://github.com/GrayCodeAI/hawk ) daemon API. It supports both synchronous and async operations, including streaming.
16+
17+ ## Features
18+
19+ - ** Sync and async** - Use ` HawkClient ` or ` AsyncHawkClient `
20+ - ** Streaming support** - Real-time response streaming
21+ - ** Context managers** - Automatic resource cleanup
22+ - ** Type hints** - Full type annotations for IDE support
23+ - ** Error handling** - Detailed exception types
424
525## Installation
626
@@ -14,191 +34,38 @@ pip install hawk-sdk
1434from hawk import HawkClient
1535
1636with HawkClient() as client:
17- # Check health
37+ # Health check
1838 health = client.health()
19- print (f " Status: { health.status } , Version: { health.version} " )
39+ print (f " Version: { health.version} " )
2040
2141 # Chat
22- response = client.chat(" Explain async/await in Python" )
42+ response = client.chat(" Explain decorators in Python" )
2343 print (response.response)
2444```
2545
2646## Async Usage
2747
2848``` python
29- import asyncio
3049from hawk import AsyncHawkClient
3150
32- async def main ():
33- async with AsyncHawkClient() as client:
34- response = await client.chat(" Hello!" )
35- print (response.response)
36-
37- asyncio.run(main())
51+ async with AsyncHawkClient() as client:
52+ response = await client.chat(" Hello!" )
53+ print (response.response)
3854```
3955
4056## Streaming
4157
4258``` python
43- from hawk import HawkClient
44-
4559with HawkClient() as client:
4660 with client.chat_stream(" Write a haiku" ) as stream:
4761 for event in stream.events():
4862 print (event.data, end = " " , flush = True )
49- print ()
50- ```
51-
52- Or collect the full text:
53-
54- ``` python
55- with HawkClient() as client:
56- with client.chat_stream(" Write a haiku" ) as stream:
57- text = stream.collect_text()
58- print (text)
59- ```
60-
61- ## Tools
62-
63- ``` python
64- from hawk import HawkClient, Tool, tool, chat_with_tools
65-
66- @tool (
67- name = " get_weather" ,
68- description = " Get current weather for a location" ,
69- parameters = {
70- " type" : " object" ,
71- " properties" : {" location" : {" type" : " string" }},
72- " required" : [" location" ],
73- },
74- )
75- def get_weather (location : str ) -> str :
76- return f " Sunny, 72F in { location} "
77-
78- with HawkClient() as client:
79- response = chat_with_tools(
80- client,
81- " What's the weather in NYC?" ,
82- tools = [get_weather],
83- )
84- print (response.response)
85- ```
86-
87- ## Workflow
88-
89- ``` python
90- from hawk import Workflow
91- from hawk.retry import RetryConfig
92-
93- def fetch (url : str ) -> str :
94- import httpx
95- return httpx.get(url).text
96-
97- def summarize (text : str ) -> str :
98- # Process the text
99- return text[:100 ]
100-
101- wf = (
102- Workflow(" fetch-and-summarize" )
103- .step(" fetch" , fetch, timeout = 10.0 )
104- .step(" summarize" , summarize, retry = RetryConfig(max_retries = 2 ))
105- .build()
106- )
107-
108- result = wf.run(" https://example.com" )
109- ```
110-
111- ## Agent
112-
113- ``` python
114- from hawk import HawkClient, Agent, AgentConfig, Tool
115-
116- weather_tool = Tool(
117- name = " get_weather" ,
118- description = " Get weather" ,
119- parameters = {" type" : " object" , " properties" : {" location" : {" type" : " string" }}},
120- fn = lambda location : f " 72F in { location} " ,
121- )
122-
123- with HawkClient() as client:
124- agent = Agent(client, AgentConfig(
125- name = " weather-bot" ,
126- model = " claude-sonnet-4-20250514" ,
127- tools = [weather_tool],
128- ))
129-
130- response = agent.chat(" What's the weather in San Francisco?" )
131- print (response.response)
132-
133- # Conversation history is maintained
134- response = agent.chat(" What about New York?" )
135- print (response.response)
136- ```
137-
138- ## Sessions
139-
140- ``` python
141- from hawk import HawkClient
142-
143- with HawkClient() as client:
144- # List sessions
145- sessions = client.list_sessions(limit = 10 )
146- for s in sessions.data:
147- print (f " { s.id} : { s.turns} turns " )
148-
149- # Get session details
150- detail = client.get_session(" session-id" )
151- print (f " Model: { detail.model} , Messages: { detail.message_count} " )
152-
153- # Get messages
154- messages = client.list_messages(" session-id" )
155- for m in messages.data:
156- print (f " [ { m.role} ] { m.content} " )
157-
158- # Delete session
159- client.delete_session(" session-id" )
160- ```
161-
162- ## Configuration
163-
164- ``` python
165- from hawk import HawkClient, RetryConfig
166-
167- client = HawkClient(
168- base_url = " http://localhost:4590" , # Daemon URL
169- api_key = " sk-..." , # Optional API key
170- timeout = 60.0 , # Request timeout in seconds
171- retry_config = RetryConfig(
172- max_retries = 5 ,
173- initial_backoff = 1.0 ,
174- max_backoff = 60.0 ,
175- ),
176- )
177- ```
178-
179- ## Error Handling
180-
181- ``` python
182- from hawk import HawkClient, NotFoundError, RateLimitError, HawkAPIError
183-
184- with HawkClient() as client:
185- try :
186- session = client.get_session(" nonexistent" )
187- except NotFoundError as e:
188- print (f " Not found: { e.message} " )
189- except RateLimitError as e:
190- print (f " Rate limited, retry after { e.retry_after} s " )
191- except HawkAPIError as e:
192- print (f " API error { e.status_code} : { e.message} " )
19363```
19464
195- ## Development
65+ ## Examples
19666
197- ``` bash
198- pip install -e " .[dev]"
199- pytest
200- ```
67+ See the [ examples/] ( examples/ ) directory for complete runnable examples.
20168
20269## License
20370
204- MIT
71+ MIT - see [ LICENSE ] ( LICENSE ) for details.
0 commit comments