Skip to content

Commit 088ebcb

Browse files
committed
just reformat
1 parent 298890b commit 088ebcb

File tree

13 files changed

+1856
-1448
lines changed

13 files changed

+1856
-1448
lines changed

patcher/src/buttercup/patcher/agents/tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import logging
66
from buttercup.common.challenge_task import CommandResult, ChallengeTask
7-
from buttercup.program_model.rest_client import CodeQueryPersistentRest
7+
from buttercup.program_model.rest_client import CodeQueryPersistentRest as CodeQueryPersistent
88
from buttercup.program_model.utils.common import Function, TypeDefinition
99
from typing import Annotated
1010
from pathlib import Path

program-model/API.md

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
This document describes the REST API for the Buttercup Program Model service, which provides code analysis and harness discovery capabilities for the Buttercup CRS system.
44

5-
## Overview
6-
7-
The Program Model REST API replaces direct execution of `codequery` and `cscope` tools, providing better isolation between components. The API exposes program analysis functionality through HTTP endpoints, allowing the patcher and seed-gen components to interact with the program model service remotely.
8-
95
## Base URL
106

117
The default base URL for the API is `http://localhost:8000`. This can be configured using the `PROGRAM_MODEL_API_URL` environment variable.
@@ -16,15 +12,15 @@ To start the API server:
1612

1713
```bash
1814
# Using the CLI command
19-
buttercup-program-model-api --host 0.0.0.0 --port 8000
15+
buttercup-program-model-api --host localhost --port 8000
2016

2117
# Or using uvicorn directly
22-
uvicorn buttercup.program_model.api.server:app --host 0.0.0.0 --port 8000
18+
uvicorn buttercup.program_model.api.server:app --host localhost --port 8000
2319
```
2420

2521
### CLI Options
2622

27-
- `--host`: Host to bind the server to (default: 0.0.0.0)
23+
- `--host`: Host to bind the server to (default: 127.0.0.1)
2824
- `--port`: Port to bind the server to (default: 8000)
2925
- `--workers`: Number of worker processes (default: 1)
3026
- `--log-level`: Log level (debug, info, warning, error, critical)
@@ -43,6 +39,7 @@ Currently, the API does not require authentication. In production deployments, c
4339
Returns the health status of the API server.
4440

4541
**Response:**
42+
4643
```json
4744
{
4845
"status": "healthy"
@@ -56,9 +53,11 @@ Returns the health status of the API server.
5653
Initialize a CodeQuery instance for a task.
5754

5855
**Parameters:**
56+
5957
- `task_id` (path): The task ID to initialize
6058

6159
**Request Body:**
60+
6261
```json
6362
{
6463
"task_id": "string",
@@ -67,6 +66,7 @@ Initialize a CodeQuery instance for a task.
6766
```
6867

6968
**Response:**
69+
7070
```json
7171
{
7272
"task_id": "string",
@@ -80,9 +80,11 @@ Initialize a CodeQuery instance for a task.
8080
Clean up a task and its associated resources.
8181

8282
**Parameters:**
83+
8384
- `task_id` (path): The task ID to cleanup
8485

8586
**Response:**
87+
8688
```json
8789
{
8890
"status": "cleaned_up",
@@ -97,6 +99,7 @@ Clean up a task and its associated resources.
9799
Search for functions in the codebase.
98100

99101
**Parameters:**
102+
100103
- `task_id` (path): The task ID
101104
- `function_name` (query): Function name to search for
102105
- `file_path` (query, optional): File path to search within
@@ -105,6 +108,7 @@ Search for functions in the codebase.
105108
- `fuzzy_threshold` (query, optional): Fuzzy matching threshold 0-100 (default: 80)
106109

107110
**Response:**
111+
108112
```json
109113
{
110114
"functions": [
@@ -129,11 +133,13 @@ Search for functions in the codebase.
129133
Get callers of a function.
130134

131135
**Parameters:**
136+
132137
- `task_id` (path): The task ID
133138
- `function_name` (path): The function name
134139
- `file_path` (query, optional): File path of the function
135140

136141
**Response:**
142+
137143
```json
138144
{
139145
"functions": [...],
@@ -146,12 +152,14 @@ Get callers of a function.
146152
Get callees of a function.
147153

148154
**Parameters:**
155+
149156
- `task_id` (path): The task ID
150157
- `function_name` (path): The function name
151158
- `file_path` (query, optional): File path of the function
152159
- `line_number` (query, optional): Line number of the function
153160

154161
**Response:**
162+
155163
```json
156164
{
157165
"functions": [...],
@@ -166,6 +174,7 @@ Get callees of a function.
166174
Search for types in the codebase.
167175

168176
**Parameters:**
177+
169178
- `task_id` (path): The task ID
170179
- `type_name` (query): Type name to search for
171180
- `file_path` (query, optional): File path to search within
@@ -174,6 +183,7 @@ Search for types in the codebase.
174183
- `fuzzy_threshold` (query, optional): Fuzzy matching threshold 0-100 (default: 80)
175184

176185
**Response:**
186+
177187
```json
178188
{
179189
"types": [
@@ -194,11 +204,13 @@ Search for types in the codebase.
194204
Get usage locations of a type.
195205

196206
**Parameters:**
207+
197208
- `task_id` (path): The task ID
198209
- `type_name` (path): The type name
199210
- `file_path` (query, optional): File path of the type
200211

201212
**Response:**
213+
202214
```json
203215
[
204216
{
@@ -216,9 +228,11 @@ Get usage locations of a type.
216228
Find libfuzzer harnesses in the codebase.
217229

218230
**Parameters:**
231+
219232
- `task_id` (path): The task ID
220233

221234
**Response:**
235+
222236
```json
223237
{
224238
"harnesses": ["string"],
@@ -231,9 +245,11 @@ Find libfuzzer harnesses in the codebase.
231245
Find jazzer harnesses in the codebase.
232246

233247
**Parameters:**
248+
234249
- `task_id` (path): The task ID
235250

236251
**Response:**
252+
237253
```json
238254
{
239255
"harnesses": ["string"],
@@ -246,10 +262,12 @@ Find jazzer harnesses in the codebase.
246262
Get source code for a specific harness.
247263

248264
**Parameters:**
265+
249266
- `task_id` (path): The task ID
250267
- `harness_name` (path): The harness name
251268

252269
**Response:**
270+
253271
```json
254272
{
255273
"file_path": "string",
@@ -268,6 +286,7 @@ The API uses standard HTTP status codes:
268286
- `500`: Internal server error
269287

270288
Error responses follow this format:
289+
271290
```json
272291
{
273292
"error": "string",
@@ -335,17 +354,22 @@ The program-model service can be deployed as a Docker container. Ensure the API
335354

336355
## Migration Guide
337356

357+
The previous version of Buttercup required components (e.g., `patcher` and `seed-gen`) to install `codequery` and `cscope` dependencies.
358+
359+
This REST API removes those requirements.
360+
338361
### From Direct CodeQuery Usage
339362

340363
1. **Remove Dependencies**: Remove `codequery` and `cscope` from Dockerfiles
341364
2. **Update Imports**: Change imports from `buttercup.program_model.codequery` to `buttercup.program_model.rest_client`
342365
3. **Update Instantiation**: Replace `CodeQueryPersistent` with `CodeQueryPersistentRest`
343-
4. **Start API Server**: Ensure the program-model API server is running
366+
4. **Start API Server**: Ensure the `program-model` API server is running
344367
5. **Configuration**: Set `PROGRAM_MODEL_API_URL` if using a non-default server location
345368

346369
### Example Migration
347370

348371
**Before:**
372+
349373
```python
350374
from buttercup.program_model.codequery import CodeQueryPersistent
351375

@@ -354,6 +378,7 @@ functions = codequery.get_functions("function_name")
354378
```
355379

356380
**After:**
381+
357382
```python
358383
from buttercup.program_model.rest_client import CodeQueryPersistentRest
359384

@@ -385,10 +410,10 @@ Enable debug logging to troubleshoot issues:
385410
buttercup-program-model-api --log-level debug
386411
```
387412

388-
### Health Check
413+
### Check Health
389414

390415
Use the health endpoint to verify the server is running:
391416

392417
```bash
393418
curl http://localhost:8000/health
394-
```
419+
```

program-model/src/buttercup/program_model/api/__cli__.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
logger = logging.getLogger(__name__)
88

99

10-
def main():
10+
def main() -> None:
1111
"""Main CLI entry point for the program-model API server."""
12-
parser = argparse.ArgumentParser(description="Buttercup Program Model REST API Server")
12+
parser = argparse.ArgumentParser(
13+
description="Buttercup Program Model REST API Server"
14+
)
1315
parser.add_argument(
1416
"--host",
15-
default="0.0.0.0",
16-
help="Host to bind the server to (default: 0.0.0.0)",
17+
default="127.0.0.1",
18+
help="Host to bind the server to (default: 127.0.0.1)",
1719
)
1820
parser.add_argument(
1921
"--port",
@@ -65,4 +67,4 @@ def main():
6567

6668

6769
if __name__ == "__main__":
68-
main()
70+
main()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"""Buttercup Program Model REST API package."""
1+
"""Buttercup Program Model REST API package."""

program-model/src/buttercup/program_model/api/models.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ class FunctionBodyModel(BaseModel):
2020
"""API model for function body."""
2121

2222
body: str = Field(..., description="Body of the function")
23-
start_line: int = Field(..., description="Start line of the function in the file (1-based)")
24-
end_line: int = Field(..., description="End line of the function in the file (1-based)")
23+
start_line: int = Field(
24+
..., description="Start line of the function in the file (1-based)"
25+
)
26+
end_line: int = Field(
27+
..., description="End line of the function in the file (1-based)"
28+
)
2529

2630
@classmethod
2731
def from_domain(cls, func_body: FunctionBody) -> FunctionBodyModel:
@@ -74,8 +78,12 @@ class TypeDefinitionModel(BaseModel):
7478
name: str = Field(..., description="Name of the type")
7579
type: TypeDefinitionType = Field(..., description="Type of the type")
7680
definition: str = Field(..., description="Definition of the type")
77-
definition_line: int = Field(..., description="Line number of the definition (1-based)")
78-
file_path: str = Field(..., description="Path to the file containing the type definition")
81+
definition_line: int = Field(
82+
..., description="Line number of the definition (1-based)"
83+
)
84+
file_path: str = Field(
85+
..., description="Path to the file containing the type definition"
86+
)
7987

8088
@classmethod
8189
def from_domain(cls, type_def: TypeDefinition) -> TypeDefinitionModel:
@@ -103,7 +111,9 @@ class TypeUsageInfoModel(BaseModel):
103111
"""API model for type usage information."""
104112

105113
name: str = Field(..., description="Name of the type being used")
106-
file_path: str = Field(..., description="Path to the file containing the type usage")
114+
file_path: str = Field(
115+
..., description="Path to the file containing the type usage"
116+
)
107117
line_number: int = Field(..., description="Line number of the type usage (1-based)")
108118

109119
@classmethod
@@ -136,25 +146,35 @@ class FunctionSearchRequest(BaseModel):
136146
"""Request model for function search."""
137147

138148
function_name: str = Field(..., description="Name of the function to search for")
139-
file_path: Optional[str] = Field(None, description="Optional file path to search within")
140-
line_number: Optional[int] = Field(None, description="Optional line number to search around")
149+
file_path: Optional[str] = Field(
150+
None, description="Optional file path to search within"
151+
)
152+
line_number: Optional[int] = Field(
153+
None, description="Optional line number to search around"
154+
)
141155
fuzzy: bool = Field(False, description="Enable fuzzy matching")
142156
fuzzy_threshold: int = Field(80, description="Fuzzy matching threshold (0-100)")
143157

144158

145159
class FunctionSearchResponse(BaseModel):
146160
"""Response model for function search."""
147161

148-
functions: list[FunctionModel] = Field(..., description="List of matching functions")
162+
functions: list[FunctionModel] = Field(
163+
..., description="List of matching functions"
164+
)
149165
total_count: int = Field(..., description="Total number of functions found")
150166

151167

152168
class TypeSearchRequest(BaseModel):
153169
"""Request model for type search."""
154170

155171
type_name: str = Field(..., description="Name of the type to search for")
156-
file_path: Optional[str] = Field(None, description="Optional file path to search within")
157-
function_name: Optional[str] = Field(None, description="Optional function name to search within")
172+
file_path: Optional[str] = Field(
173+
None, description="Optional file path to search within"
174+
)
175+
function_name: Optional[str] = Field(
176+
None, description="Optional function name to search within"
177+
)
158178
fuzzy: bool = Field(False, description="Enable fuzzy matching")
159179
fuzzy_threshold: int = Field(80, description="Fuzzy matching threshold (0-100)")
160180

@@ -193,4 +213,4 @@ class ErrorResponse(BaseModel):
193213

194214
error: str = Field(..., description="Error message")
195215
detail: Optional[str] = Field(None, description="Additional error details")
196-
code: Optional[str] = Field(None, description="Error code")
216+
code: Optional[str] = Field(None, description="Error code")

0 commit comments

Comments
 (0)