Skip to content

Commit b1f9886

Browse files
committed
Cleaned up code
1 parent 3af909a commit b1f9886

File tree

6 files changed

+312
-119
lines changed

6 files changed

+312
-119
lines changed

‎src/hackingBuddyGPT/usecases/web_api_testing/simple_openapi_documentation.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ def _handle_response(self, completion, response):
9797
self.console.print(Panel(result[:30], title="tool"))
9898
result_str = self.response_handler.parse_http_status_line(result)
9999
self._prompt_history.append(tool_message(result_str, tool_call_id))
100-
invalid_flags = ["recorded","Not a valid HTTP method" ]
101-
if not result_str in invalid_flags :
100+
invalid_flags = ["recorded","Not a valid HTTP method", "404" ,"Client Error: Not Found"]
101+
print(f'result_str:{result_str}')
102+
if not result_str in invalid_flags or any(item in result_str for item in invalid_flags):
102103
self.documentation_handler.update_openapi_spec(response, result)
103104
self.documentation_handler.write_openapi_to_yaml()
104105
self.prompt_engineer.schemas = self.documentation_handler.schemas

‎src/hackingBuddyGPT/usecases/web_api_testing/utils/documentation_handler.py‎

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
import os
22
import yaml
33
from datetime import datetime
4-
54
from hackingBuddyGPT.capabilities.yamlFile import YAMLFile
65

7-
86
class DocumentationHandler:
9-
"""Handles the generation and updating of an OpenAPI specification document based on dynamic API responses."""
7+
"""
8+
Handles the generation and updating of an OpenAPI specification document based on dynamic API responses.
9+
10+
Attributes:
11+
response_handler (object): An instance of the response handler for processing API responses.
12+
schemas (dict): A dictionary to store API schemas.
13+
filename (str): The filename for the OpenAPI specification file.
14+
openapi_spec (dict): The OpenAPI specification document structure.
15+
llm_handler (object): An instance of the LLM handler for interacting with the LLM.
16+
api_key (str): The API key for accessing the LLM.
17+
file_path (str): The path to the directory where the OpenAPI specification file will be stored.
18+
file (str): The complete path to the OpenAPI specification file.
19+
_capabilities (dict): A dictionary to store capabilities related to YAML file handling.
20+
"""
1021

1122
def __init__(self, llm_handler, response_handler):
12-
"""Initializes the handler with a template OpenAPI specification."""
23+
"""
24+
Initializes the handler with a template OpenAPI specification.
25+
26+
Args:
27+
llm_handler (object): An instance of the LLM handler for interacting with the LLM.
28+
response_handler (object): An instance of the response handler for processing API responses.
29+
"""
1330
self.response_handler = response_handler
1431
self.schemas = {}
1532
self.filename = f"openapi_spec_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.yaml"
@@ -29,7 +46,6 @@ def __init__(self, llm_handler, response_handler):
2946
current_path = os.path.dirname(os.path.abspath(__file__))
3047
self.file_path = os.path.join(current_path, "openapi_spec")
3148
self.file = os.path.join(self.file_path, self.filename)
32-
yamls = []
3349
self._capabilities = {
3450
"yaml": YAMLFile()
3551
}
@@ -39,47 +55,46 @@ def update_openapi_spec(self, resp, result):
3955
Updates the OpenAPI specification based on the API response provided.
4056
4157
Args:
42-
- response: The response object containing details like the path and method which should be documented.
58+
resp (object): The response object containing details like the path and method which should be documented.
59+
result (str): The result of the API call.
4360
"""
4461
request = resp.action
4562

46-
47-
if request.__class__.__name__ == 'RecordNote': # TODO check why isinstance does not work
63+
if request.__class__.__name__ == 'RecordNote': # TODO: check why isinstance does not work
4864
self.check_openapi_spec(resp)
4965
if request.__class__.__name__ == 'HTTPRequest':
5066
path = request.path
5167
method = request.method
52-
print(f'method:{method}')
68+
print(f'method: {method}')
5369
# Ensure that path and method are not None and method has no numeric characters
5470
if path and method:
5571
# Initialize the path if not already present
5672
if path not in self.openapi_spec['endpoints']:
5773
self.openapi_spec['endpoints'][path] = {}
5874
# Update the method description within the path
5975
example, reference, self.openapi_spec = self.response_handler.parse_http_response_to_openapi_example(self.openapi_spec, result, path, method)
60-
if example != None or reference != None:
76+
if example is not None or reference is not None:
6177
self.openapi_spec['endpoints'][path][method.lower()] = {
62-
"summary": f"{method} operation on {path}",
63-
"responses": {
64-
"200": {
65-
"description": "Successful response",
66-
"content": {
67-
"application/json": {
68-
"schema": {
69-
"$ref": reference
70-
},
71-
"examples": example
78+
"summary": f"{method} operation on {path}",
79+
"responses": {
80+
"200": {
81+
"description": "Successful response",
82+
"content": {
83+
"application/json": {
84+
"schema": {
85+
"$ref": reference
86+
},
87+
"examples": example
88+
}
7289
}
7390
}
7491
}
75-
7692
}
77-
}
78-
79-
8093

8194
def write_openapi_to_yaml(self):
82-
"""Writes the updated OpenAPI specification to a YAML file with a timestamped filename."""
95+
"""
96+
Writes the updated OpenAPI specification to a YAML file with a timestamped filename.
97+
"""
8398
try:
8499
# Prepare data to be written to YAML
85100
openapi_data = {
@@ -100,20 +115,14 @@ def write_openapi_to_yaml(self):
100115
except Exception as e:
101116
raise Exception(f"Error writing YAML file: {e}")
102117

103-
104-
105-
106118
def check_openapi_spec(self, note):
107119
"""
108-
Uses OpenAI's GPT model to generate a complete OpenAPI specification based on a natural language description.
120+
Uses OpenAI's GPT model to generate a complete OpenAPI specification based on a natural language description.
109121
110-
Parameters:
111-
- api_key: str. Your OpenAI API key.
112-
- file_path: str. Path to the YAML file to update.
113-
- description: str. A detailed description of the entire API.
114-
"""
122+
Args:
123+
note (object): The note object containing the description of the API.
124+
"""
115125
description = self.response_handler.extract_description(note)
116126
from hackingBuddyGPT.usecases.web_api_testing.utils.yaml_assistant import YamlFileAssistant
117127
yaml_file_assistant = YamlFileAssistant(self.file_path, self.llm_handler)
118128
yaml_file_assistant.run(description)
119-

‎src/hackingBuddyGPT/usecases/web_api_testing/utils/llm_handler.py‎

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,63 @@
11
from hackingBuddyGPT.capabilities.capability import capabilities_to_action_model
22

3-
43
class LLMHandler(object):
4+
"""
5+
LLMHandler is a class responsible for managing interactions with a large language model (LLM).
6+
It handles the execution of prompts and the management of created objects based on the capabilities.
7+
8+
Attributes:
9+
llm (object): The large language model to interact with.
10+
_capabilities (dict): A dictionary of capabilities that define the actions the LLM can perform.
11+
created_objects (dict): A dictionary to keep track of created objects by their type.
12+
"""
13+
514
def __init__(self, llm, capabilities):
15+
"""
16+
Initializes the LLMHandler with the specified LLM and capabilities.
17+
18+
Args:
19+
llm (object): The large language model to interact with.
20+
capabilities (dict): A dictionary of capabilities that define the actions the LLM can perform.
21+
"""
622
self.llm = llm
723
self._capabilities = capabilities
824
self.created_objects = {}
925

1026
def call_llm(self, prompt):
11-
return self.llm.instructor.chat.completions.create_with_completion(model=self.llm.model, messages=prompt, response_model=capabilities_to_action_model(self._capabilities))
27+
"""
28+
Calls the LLM with the specified prompt and retrieves the response.
29+
30+
Args:
31+
prompt (list): The prompt messages to send to the LLM.
32+
33+
Returns:
34+
response (object): The response from the LLM.
35+
"""
36+
return self.llm.instructor.chat.completions.create_with_completion(
37+
model=self.llm.model,
38+
messages=prompt,
39+
response_model=capabilities_to_action_model(self._capabilities)
40+
)
1241

1342
def add_created_object(self, created_object, object_type):
43+
"""
44+
Adds a created object to the dictionary of created objects, categorized by object type.
45+
46+
Args:
47+
created_object (object): The object that was created.
48+
object_type (str): The type/category of the created object.
49+
"""
1450
if object_type not in self.created_objects:
1551
self.created_objects[object_type] = []
1652
if len(self.created_objects[object_type]) < 7:
1753
self.created_objects[object_type].append(created_object)
1854

1955
def get_created_objects(self):
56+
"""
57+
Retrieves the dictionary of created objects and prints its contents.
58+
59+
Returns:
60+
dict: The dictionary of created objects.
61+
"""
2062
print(f'created_objects: {self.created_objects}')
2163
return self.created_objects
22-

‎src/hackingBuddyGPT/usecases/web_api_testing/utils/openapi_converter.py‎

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
import os.path
2-
32
import yaml
43
import json
54

6-
75
class OpenAPISpecificationConverter:
6+
"""
7+
OpenAPISpecificationConverter is a class for converting OpenAPI specification files between YAML and JSON formats.
8+
9+
Attributes:
10+
base_directory (str): The base directory for the output files.
11+
"""
12+
813
def __init__(self, base_directory):
14+
"""
15+
Initializes the OpenAPISpecificationConverter with the specified base directory.
16+
17+
Args:
18+
base_directory (str): The base directory for the output files.
19+
"""
920
self.base_directory = base_directory
1021

1122
def convert_file(self, input_filepath, output_directory, input_type, output_type):
1223
"""
13-
Generic method to convert files between YAML and JSON.
24+
Converts files between YAML and JSON formats.
25+
26+
Args:
27+
input_filepath (str): The path to the input file.
28+
output_directory (str): The subdirectory for the output files.
29+
input_type (str): The type of the input file ('yaml' or 'json').
30+
output_type (str): The type of the output file ('json' or 'yaml').
1431
15-
:param input_filepath: Path to the input file.
16-
:param output_directory: Subdirectory for the output files.
17-
:param input_type: Type of the input file ('yaml' or 'json').
18-
:param output_type: Type of the output file ('json' or 'yaml').
32+
Returns:
33+
str: The path to the converted output file, or None if an error occurred.
1934
"""
2035
try:
2136
filename = os.path.basename(input_filepath)
@@ -44,11 +59,27 @@ def convert_file(self, input_filepath, output_directory, input_type, output_type
4459
return None
4560

4661
def yaml_to_json(self, yaml_filepath):
47-
"""Convert a YAML file to a JSON file."""
62+
"""
63+
Converts a YAML file to a JSON file.
64+
65+
Args:
66+
yaml_filepath (str): The path to the YAML file to be converted.
67+
68+
Returns:
69+
str: The path to the converted JSON file, or None if an error occurred.
70+
"""
4871
return self.convert_file(yaml_filepath, "json", 'yaml', 'json')
4972

5073
def json_to_yaml(self, json_filepath):
51-
"""Convert a JSON file to a YAML file."""
74+
"""
75+
Converts a JSON file to a YAML file.
76+
77+
Args:
78+
json_filepath (str): The path to the JSON file to be converted.
79+
80+
Returns:
81+
str: The path to the converted YAML file, or None if an error occurred.
82+
"""
5283
return self.convert_file(json_filepath, "yaml", 'json', 'yaml')
5384

5485

@@ -61,4 +92,5 @@ def json_to_yaml(self, json_filepath):
6192
json_file = converter.yaml_to_json(yaml_input)
6293

6394
# Convert JSON to YAML
64-
yaml_file = converter.json_to_yaml(json_file)
95+
if json_file:
96+
converter.json_to_yaml(json_file)

‎src/hackingBuddyGPT/usecases/web_api_testing/utils/openapi_parser.py‎

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,73 @@
11
import yaml
22

33
class OpenAPISpecificationParser:
4+
"""
5+
OpenAPISpecificationParser is a class for parsing and extracting information from an OpenAPI specification file.
6+
7+
Attributes:
8+
filepath (str): The path to the OpenAPI specification YAML file.
9+
api_data (dict): The parsed data from the YAML file.
10+
"""
11+
412
def __init__(self, filepath):
13+
"""
14+
Initializes the OpenAPISpecificationParser with the specified file path.
15+
16+
Args:
17+
filepath (str): The path to the OpenAPI specification YAML file.
18+
"""
519
self.filepath = filepath
620
self.api_data = self.load_yaml()
721

822
def load_yaml(self):
9-
"""Load YAML data from the specified file."""
23+
"""
24+
Loads YAML data from the specified file.
25+
26+
Returns:
27+
dict: The parsed data from the YAML file.
28+
"""
1029
with open(self.filepath, 'r') as file:
1130
return yaml.safe_load(file)
1231

1332
def get_servers(self):
14-
"""Retrieve the list of server URLs."""
33+
"""
34+
Retrieves the list of server URLs from the OpenAPI specification.
35+
36+
Returns:
37+
list: A list of server URLs.
38+
"""
1539
return [server['url'] for server in self.api_data.get('servers', [])]
1640

1741
def get_paths(self):
18-
"""Retrieve all API paths and their methods."""
42+
"""
43+
Retrieves all API paths and their methods from the OpenAPI specification.
44+
45+
Returns:
46+
dict: A dictionary with API paths as keys and methods as values.
47+
"""
1948
paths_info = {}
2049
paths = self.api_data.get('paths', {})
2150
for path, methods in paths.items():
2251
paths_info[path] = {method: details for method, details in methods.items()}
2352
return paths_info
2453

2554
def get_operations(self, path):
26-
"""Retrieve operations for a specific path."""
55+
"""
56+
Retrieves operations for a specific path from the OpenAPI specification.
57+
58+
Args:
59+
path (str): The API path to retrieve operations for.
60+
61+
Returns:
62+
dict: A dictionary with methods as keys and operation details as values.
63+
"""
2764
return self.api_data['paths'].get(path, {})
2865

2966
def print_api_details(self):
30-
"""Prints details of the API extracted from the OpenAPI document."""
67+
"""
68+
Prints details of the API extracted from the OpenAPI document, including title, version, servers,
69+
paths, and operations.
70+
"""
3171
print("API Title:", self.api_data['info']['title'])
3272
print("API Version:", self.api_data['info']['version'])
3373
print("Servers:", self.get_servers())
@@ -42,5 +82,6 @@ def print_api_details(self):
4282
# Usage example
4383
if __name__ == '__main__':
4484
openapi_parser = OpenAPISpecificationParser(
45-
'/hackingBuddyGPT/usecases/web_api_testing/openapi_spec/openapi_spec_2024-06-13_17-16-25.yaml')
85+
'/hackingBuddyGPT/usecases/web_api_testing/openapi_spec/openapi_spec_2024-06-13_17-16-25.yaml'
86+
)
4687
openapi_parser.print_api_details()

0 commit comments

Comments
 (0)