add more docs & comments
Browse files- CodeTestingAtomicFlow.py +29 -0
- README.md +115 -13
- TestCodeFileEditAtomicFlow.py +40 -1
- TestCodeFlow.py +29 -0
CodeTestingAtomicFlow.py
CHANGED
@@ -13,14 +13,28 @@ class CodeTestingAtomicFlow(InterpreterAtomicFlow):
|
|
13 |
|
14 |
*Output Interface*:
|
15 |
- `feedback`: Feedback from the test (i.e. test results).
|
|
|
|
|
|
|
|
|
16 |
"""
|
17 |
def _open_file_and_wait_for_file_update(self, file_location, check_interval=1):
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
process = subprocess.Popen(["code", "--wait", file_location])
|
19 |
while True:
|
20 |
if process.poll() is not None:
|
21 |
break
|
22 |
time.sleep(check_interval)
|
23 |
def _prepare_code_and_lang(self, input_data: Dict[str, Any]):
|
|
|
|
|
|
|
|
|
24 |
file_location = input_data["temp_code_file_location"]
|
25 |
input_data["language"] = "python"
|
26 |
with open(file_location, "r") as file:
|
@@ -28,15 +42,30 @@ class CodeTestingAtomicFlow(InterpreterAtomicFlow):
|
|
28 |
input_data["code"] = code_str
|
29 |
|
30 |
def _check_input(self, input_data: Dict[str, Any]):
|
|
|
|
|
|
|
|
|
|
|
31 |
assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to CodeTestingAtomicFlow"
|
32 |
|
33 |
def _delete_file(self, file_location):
|
|
|
|
|
|
|
|
|
34 |
if os.path.exists(file_location):
|
35 |
os.remove(file_location)
|
36 |
|
37 |
def run(
|
38 |
self,
|
39 |
input_data: Dict[str, Any]):
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
self._check_input(input_data)
|
41 |
file_loc = input_data["temp_code_file_location"]
|
42 |
self._open_file_and_wait_for_file_update(file_loc)
|
|
|
13 |
|
14 |
*Output Interface*:
|
15 |
- `feedback`: Feedback from the test (i.e. test results).
|
16 |
+
|
17 |
+
*Configuration Parameters*:
|
18 |
+
- `input_interface`: the input interface of the atomic flow.
|
19 |
+
- `output_interface`: the output interface of the atomic flow.
|
20 |
"""
|
21 |
def _open_file_and_wait_for_file_update(self, file_location, check_interval=1):
|
22 |
+
"""Opens the file in VSCode and waits for the file to be updated.
|
23 |
+
:param file_location: The location of the file to be opened.
|
24 |
+
:type file_location: str
|
25 |
+
:param check_interval: The interval at which the file is checked for updates.
|
26 |
+
:type check_interval: int
|
27 |
+
"""
|
28 |
process = subprocess.Popen(["code", "--wait", file_location])
|
29 |
while True:
|
30 |
if process.poll() is not None:
|
31 |
break
|
32 |
time.sleep(check_interval)
|
33 |
def _prepare_code_and_lang(self, input_data: Dict[str, Any]):
|
34 |
+
"""Prepares the code and language to be passed to the interpreter.
|
35 |
+
:param input_data: The input data to the atomic flow.
|
36 |
+
:type input_data: Dict[str, Any]
|
37 |
+
"""
|
38 |
file_location = input_data["temp_code_file_location"]
|
39 |
input_data["language"] = "python"
|
40 |
with open(file_location, "r") as file:
|
|
|
42 |
input_data["code"] = code_str
|
43 |
|
44 |
def _check_input(self, input_data: Dict[str, Any]):
|
45 |
+
"""Checks if the input data contains the required keys.
|
46 |
+
:param input_data: The input data to the atomic flow.
|
47 |
+
:type input_data: Dict[str, Any]
|
48 |
+
:raises AssertionError: If the input data does not contain the required keys.
|
49 |
+
"""
|
50 |
assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to CodeTestingAtomicFlow"
|
51 |
|
52 |
def _delete_file(self, file_location):
|
53 |
+
"""Deletes the file at the given location.
|
54 |
+
:param file_location: The location of the file to be deleted.
|
55 |
+
:type file_location: str
|
56 |
+
"""
|
57 |
if os.path.exists(file_location):
|
58 |
os.remove(file_location)
|
59 |
|
60 |
def run(
|
61 |
self,
|
62 |
input_data: Dict[str, Any]):
|
63 |
+
"""Runs the atomic flow.
|
64 |
+
:param input_data: The input data to the atomic flow.
|
65 |
+
:type input_data: Dict[str, Any]
|
66 |
+
:return: The output data of the atomic flow.
|
67 |
+
:rtype: Dict[str, Any]
|
68 |
+
"""
|
69 |
self._check_input(input_data)
|
70 |
file_loc = input_data["temp_code_file_location"]
|
71 |
self._open_file_and_wait_for_file_update(file_loc)
|
README.md
CHANGED
@@ -1,11 +1,29 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
```
|
4 |
code
|
5 |
|
|
6 |
v
|
7 |
+-------------------+
|
8 |
-
| TestCodeFileEdit | Edit a temp code file with the code to be tested and necessary imports (manually added): https://huggingface.co/
|
9 |
+-------------------+
|
10 |
|
|
11 |
| (temp_code_file_location)
|
@@ -23,17 +41,8 @@
|
|
23 |
|
24 |
```
|
25 |
Memory_files:
|
26 |
-
- library.py
|
27 |
-
|
28 |
-
# Table of Contents
|
29 |
|
30 |
-
* [TestCodeFlow](#TestCodeFlow)
|
31 |
-
* [TestCodeFlow](#TestCodeFlow.TestCodeFlow)
|
32 |
-
* [TestCodeFileEditAtomicFlow](#TestCodeFileEditAtomicFlow)
|
33 |
-
* [TestCodeFileEditAtomicFlow](#TestCodeFileEditAtomicFlow.TestCodeFileEditAtomicFlow)
|
34 |
-
* [\_\_init\_\_](#__init__)
|
35 |
-
* [CodeTestingAtomicFlow](#CodeTestingAtomicFlow)
|
36 |
-
* [CodeTestingAtomicFlow](#CodeTestingAtomicFlow.CodeTestingAtomicFlow)
|
37 |
|
38 |
<a id="TestCodeFlow"></a>
|
39 |
|
@@ -61,6 +70,65 @@ This class is used to test code. It is a sequential flow that runs the following
|
|
61 |
*Output Interface*:
|
62 |
- `feedback` (str): The test results.
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
<a id="TestCodeFileEditAtomicFlow"></a>
|
65 |
|
66 |
# TestCodeFileEditAtomicFlow
|
@@ -73,7 +141,19 @@ This class is used to test code. It is a sequential flow that runs the following
|
|
73 |
class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow)
|
74 |
```
|
75 |
|
76 |
-
Refer to: https://huggingface.co/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
<a id="__init__"></a>
|
79 |
|
@@ -99,3 +179,25 @@ This class inherits from InterpreterAtomicFlow and is used to test code.
|
|
99 |
*Output Interface*:
|
100 |
- `feedback`: Feedback from the test (i.e. test results).
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Table of Contents
|
2 |
+
|
3 |
+
* [Structure of TestCodeFlow](#structure-of-testcodeflow)
|
4 |
+
* [TestCodeFlow](#TestCodeFlow)
|
5 |
+
* [TestCodeFlow](#TestCodeFlow.TestCodeFlow)
|
6 |
+
* [\_\_init\_\_](#TestCodeFlow.TestCodeFlow.__init__)
|
7 |
+
* [instantiate\_from\_config](#TestCodeFlow.TestCodeFlow.instantiate_from_config)
|
8 |
+
* [run](#TestCodeFlow.TestCodeFlow.run)
|
9 |
+
* [TestCodeFileEditAtomicFlow](#TestCodeFileEditAtomicFlow)
|
10 |
+
* [TestCodeFileEditAtomicFlow](#TestCodeFileEditAtomicFlow.TestCodeFileEditAtomicFlow)
|
11 |
+
* [run](#run)
|
12 |
+
* [\_\_init\_\_](#__init__)
|
13 |
+
* [CodeTestingAtomicFlow](#CodeTestingAtomicFlow)
|
14 |
+
* [CodeTestingAtomicFlow](#CodeTestingAtomicFlow.CodeTestingAtomicFlow)
|
15 |
+
* [run](#CodeTestingAtomicFlow.CodeTestingAtomicFlow.run)
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
# Structure of TestCodeFlow
|
20 |
|
21 |
```
|
22 |
code
|
23 |
|
|
24 |
v
|
25 |
+-------------------+
|
26 |
+
| TestCodeFileEdit | Edit a temp code file with the code to be tested and necessary imports (manually added): https://huggingface.co/aiflows/TestCodeFlowModule/blob/main/TestCodeFileEditAtomicFlow.py
|
27 |
+-------------------+
|
28 |
|
|
29 |
| (temp_code_file_location)
|
|
|
41 |
|
42 |
```
|
43 |
Memory_files:
|
44 |
+
- `library.py`
|
|
|
|
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
<a id="TestCodeFlow"></a>
|
48 |
|
|
|
70 |
*Output Interface*:
|
71 |
- `feedback` (str): The test results.
|
72 |
|
73 |
+
*Configuration Parameters*:
|
74 |
+
- `memory_files`: The memory files to be used in the flow, typically we need to have the code library as memory file here.
|
75 |
+
- `input_interface`: The input interface of the flow.
|
76 |
+
- `output_interface`: The output interface of the flow.
|
77 |
+
- `subflows_config`: The subflows configuration.
|
78 |
+
- `topology`: The topology of the subflows.
|
79 |
+
|
80 |
+
<a id="TestCodeFlow.TestCodeFlow.__init__"></a>
|
81 |
+
|
82 |
+
#### \_\_init\_\_
|
83 |
+
|
84 |
+
```python
|
85 |
+
def __init__(memory_files: Dict[str, Any], **kwargs)
|
86 |
+
```
|
87 |
+
|
88 |
+
This function instantiates the class.
|
89 |
+
|
90 |
+
**Arguments**:
|
91 |
+
|
92 |
+
- `memory_files` (`Dict[str, Any]`): The memory files to be used in the flow, typically we need to have the code library as memory file here.
|
93 |
+
- `kwargs` (`Any`): The keyword arguments.
|
94 |
+
|
95 |
+
<a id="TestCodeFlow.TestCodeFlow.instantiate_from_config"></a>
|
96 |
+
|
97 |
+
#### instantiate\_from\_config
|
98 |
+
|
99 |
+
```python
|
100 |
+
@classmethod
|
101 |
+
def instantiate_from_config(cls, config)
|
102 |
+
```
|
103 |
+
|
104 |
+
This function instantiates the class from a configuration dictionary.
|
105 |
+
|
106 |
+
**Arguments**:
|
107 |
+
|
108 |
+
- `config` (`Dict[str, Any]`): The configuration dictionary.
|
109 |
+
|
110 |
+
**Returns**:
|
111 |
+
|
112 |
+
`TestCodeFlow`: The instantiated class.
|
113 |
+
|
114 |
+
<a id="TestCodeFlow.TestCodeFlow.run"></a>
|
115 |
+
|
116 |
+
#### run
|
117 |
+
|
118 |
+
```python
|
119 |
+
def run(input_data: Dict[str, Any]) -> Dict[str, Any]
|
120 |
+
```
|
121 |
+
|
122 |
+
This function runs the flow.
|
123 |
+
|
124 |
+
**Arguments**:
|
125 |
+
|
126 |
+
- `input_data` (`Dict[str, Any]`): The input data.
|
127 |
+
|
128 |
+
**Returns**:
|
129 |
+
|
130 |
+
`Dict[str, Any]`: The output data.
|
131 |
+
|
132 |
<a id="TestCodeFileEditAtomicFlow"></a>
|
133 |
|
134 |
# TestCodeFileEditAtomicFlow
|
|
|
141 |
class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow)
|
142 |
```
|
143 |
|
144 |
+
Refer to: https://huggingface.co/aiflows/CodeFileEditFlowModule/tree/main
|
145 |
+
|
146 |
+
*Input Interface*:
|
147 |
+
- `code`: str
|
148 |
+
- `memory_files`: Dict[str, str]
|
149 |
+
|
150 |
+
*Output Interface*:
|
151 |
+
- `code_editor_output`: str, the code editor output
|
152 |
+
- `temp_code_file_location`: str, the location of the temporary code file
|
153 |
+
|
154 |
+
<a id="run"></a>
|
155 |
+
|
156 |
+
# run
|
157 |
|
158 |
<a id="__init__"></a>
|
159 |
|
|
|
179 |
*Output Interface*:
|
180 |
- `feedback`: Feedback from the test (i.e. test results).
|
181 |
|
182 |
+
*Configuration Parameters*:
|
183 |
+
- `input_interface`: the input interface of the atomic flow.
|
184 |
+
- `output_interface`: the output interface of the atomic flow.
|
185 |
+
|
186 |
+
<a id="CodeTestingAtomicFlow.CodeTestingAtomicFlow.run"></a>
|
187 |
+
|
188 |
+
#### run
|
189 |
+
|
190 |
+
```python
|
191 |
+
def run(input_data: Dict[str, Any])
|
192 |
+
```
|
193 |
+
|
194 |
+
Runs the atomic flow.
|
195 |
+
|
196 |
+
**Arguments**:
|
197 |
+
|
198 |
+
- `input_data` (`Dict[str, Any]`): The input data to the atomic flow.
|
199 |
+
|
200 |
+
**Returns**:
|
201 |
+
|
202 |
+
`Dict[str, Any]`: The output data of the atomic flow.
|
203 |
+
|
TestCodeFileEditAtomicFlow.py
CHANGED
@@ -3,8 +3,25 @@ from typing import Dict, Any
|
|
3 |
from flow_modules.aiflows.CodeFileEditFlowModule import CodeFileEditAtomicFlow
|
4 |
|
5 |
class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
|
6 |
-
"""Refer to: https://huggingface.co/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
def _generate_import_statement(self, code_lib_location):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
module_dir = os.path.dirname(code_lib_location)
|
9 |
module_name = os.path.splitext(os.path.basename(code_lib_location))[0]
|
10 |
|
@@ -16,6 +33,15 @@ class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
|
|
16 |
return import_code
|
17 |
|
18 |
def _generate_content(self, code_lib_location, code_str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
import_code_lib_str = self._generate_import_statement(code_lib_location)
|
20 |
content = (
|
21 |
"# Don't touch this import statement \n"
|
@@ -33,11 +59,24 @@ class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
|
|
33 |
return content
|
34 |
|
35 |
def _generate_temp_file_location(self, code_lib_location):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
directory = os.path.dirname(code_lib_location)
|
37 |
ret = os.path.join(directory, 'temp_tests.py')
|
38 |
return ret
|
39 |
|
40 |
def _check_input(self, input_data: Dict[str, Any]):
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
assert "code" in input_data, "code is not passed to TestCodeFileEditAtomicFlow"
|
42 |
assert "memory_files" in input_data, "memory_files is not passed to TestCodeFileEditAtomicFlow"
|
43 |
|
|
|
3 |
from flow_modules.aiflows.CodeFileEditFlowModule import CodeFileEditAtomicFlow
|
4 |
|
5 |
class TestCodeFileEditAtomicFlow(CodeFileEditAtomicFlow):
|
6 |
+
"""Refer to: https://huggingface.co/aiflows/CodeFileEditFlowModule/tree/main
|
7 |
+
|
8 |
+
*Input Interface*:
|
9 |
+
- `code`: str
|
10 |
+
- `memory_files`: Dict[str, str]
|
11 |
+
|
12 |
+
*Output Interface*:
|
13 |
+
- `code_editor_output`: str, the code editor output
|
14 |
+
- `temp_code_file_location`: str, the location of the temporary code file
|
15 |
+
|
16 |
+
"""
|
17 |
def _generate_import_statement(self, code_lib_location):
|
18 |
+
"""
|
19 |
+
Generate the import statement for the code library.
|
20 |
+
:param code_lib_location: the location of the code library
|
21 |
+
:type code_lib_location: str
|
22 |
+
:return: the import statement
|
23 |
+
:rtype: str
|
24 |
+
"""
|
25 |
module_dir = os.path.dirname(code_lib_location)
|
26 |
module_name = os.path.splitext(os.path.basename(code_lib_location))[0]
|
27 |
|
|
|
33 |
return import_code
|
34 |
|
35 |
def _generate_content(self, code_lib_location, code_str) -> str:
|
36 |
+
"""
|
37 |
+
Generate the content of the temporary code file.
|
38 |
+
:param code_lib_location: the location of the code library
|
39 |
+
:type code_lib_location: str
|
40 |
+
:param code_str: the code string
|
41 |
+
:type code_str: str
|
42 |
+
:return: the content of the temporary code file
|
43 |
+
:rtype: str
|
44 |
+
"""
|
45 |
import_code_lib_str = self._generate_import_statement(code_lib_location)
|
46 |
content = (
|
47 |
"# Don't touch this import statement \n"
|
|
|
59 |
return content
|
60 |
|
61 |
def _generate_temp_file_location(self, code_lib_location):
|
62 |
+
"""
|
63 |
+
Generate the location of the temporary code file.
|
64 |
+
:param code_lib_location: the location of the code library
|
65 |
+
:type code_lib_location: str
|
66 |
+
:return: the location of the temporary code file
|
67 |
+
:rtype: str
|
68 |
+
"""
|
69 |
directory = os.path.dirname(code_lib_location)
|
70 |
ret = os.path.join(directory, 'temp_tests.py')
|
71 |
return ret
|
72 |
|
73 |
def _check_input(self, input_data: Dict[str, Any]):
|
74 |
+
"""
|
75 |
+
Check if the input data is valid.
|
76 |
+
:param input_data: the input data
|
77 |
+
:type input_data: Dict[str, Any]
|
78 |
+
:raises AssertionError: if code or memory_files is not passed to TestCodeFileEditAtomicFlow
|
79 |
+
"""
|
80 |
assert "code" in input_data, "code is not passed to TestCodeFileEditAtomicFlow"
|
81 |
assert "memory_files" in input_data, "memory_files is not passed to TestCodeFileEditAtomicFlow"
|
82 |
|
TestCodeFlow.py
CHANGED
@@ -21,6 +21,14 @@ class TestCodeFlow(SequentialFlow):
|
|
21 |
|
22 |
*Output Interface*:
|
23 |
- `feedback` (str): The test results.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
"""
|
25 |
REQUIRED_KEYS_CONFIG = ["max_rounds", "early_exit_key", "topology", "memory_files"]
|
26 |
|
@@ -29,11 +37,25 @@ class TestCodeFlow(SequentialFlow):
|
|
29 |
memory_files: Dict[str, Any],
|
30 |
**kwargs
|
31 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
super().__init__(**kwargs)
|
33 |
self.memory_files = memory_files
|
34 |
|
35 |
@classmethod
|
36 |
def instantiate_from_config(cls, config):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
flow_config = deepcopy(config)
|
38 |
|
39 |
kwargs = {"flow_config": flow_config}
|
@@ -49,6 +71,13 @@ class TestCodeFlow(SequentialFlow):
|
|
49 |
return cls(**kwargs)
|
50 |
|
51 |
def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
# ~~~ sets the input_data in the flow_state dict ~~~
|
53 |
self._state_update_dict(update_data=input_data)
|
54 |
|
|
|
21 |
|
22 |
*Output Interface*:
|
23 |
- `feedback` (str): The test results.
|
24 |
+
|
25 |
+
*Configuration Parameters*:
|
26 |
+
- `memory_files`: The memory files to be used in the flow, typically we need to have the code library as memory file here.
|
27 |
+
- `input_interface`: The input interface of the flow.
|
28 |
+
- `output_interface`: The output interface of the flow.
|
29 |
+
- `subflows_config`: The subflows configuration.
|
30 |
+
- `topology`: The topology of the subflows.
|
31 |
+
|
32 |
"""
|
33 |
REQUIRED_KEYS_CONFIG = ["max_rounds", "early_exit_key", "topology", "memory_files"]
|
34 |
|
|
|
37 |
memory_files: Dict[str, Any],
|
38 |
**kwargs
|
39 |
):
|
40 |
+
"""
|
41 |
+
This function instantiates the class.
|
42 |
+
:param memory_files: The memory files to be used in the flow, typically we need to have the code library as memory file here.
|
43 |
+
:type memory_files: Dict[str, Any]
|
44 |
+
:param kwargs: The keyword arguments.
|
45 |
+
:type kwargs: Any
|
46 |
+
"""
|
47 |
super().__init__(**kwargs)
|
48 |
self.memory_files = memory_files
|
49 |
|
50 |
@classmethod
|
51 |
def instantiate_from_config(cls, config):
|
52 |
+
"""
|
53 |
+
This function instantiates the class from a configuration dictionary.
|
54 |
+
:param config: The configuration dictionary.
|
55 |
+
:type config: Dict[str, Any]
|
56 |
+
:return: The instantiated class.
|
57 |
+
:rtype: TestCodeFlow
|
58 |
+
"""
|
59 |
flow_config = deepcopy(config)
|
60 |
|
61 |
kwargs = {"flow_config": flow_config}
|
|
|
71 |
return cls(**kwargs)
|
72 |
|
73 |
def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
|
74 |
+
"""
|
75 |
+
This function runs the flow.
|
76 |
+
:param input_data: The input data.
|
77 |
+
:type input_data: Dict[str, Any]
|
78 |
+
:return: The output data.
|
79 |
+
:rtype: Dict[str, Any]
|
80 |
+
"""
|
81 |
# ~~~ sets the input_data in the flow_state dict ~~~
|
82 |
self._state_update_dict(update_data=input_data)
|
83 |
|