1+ from typing import Optional
2+
13import requests
24
5+ from plain2code_state import RunState
6+
37
48class FunctionalRequirementTooComplex (Exception ):
59 def __init__ (self , message , proposed_breakdown = None ):
@@ -36,6 +40,14 @@ class LinkMustHaveTextSpecified(Exception):
3640 pass
3741
3842
43+ class NoRenderFound (Exception ):
44+ pass
45+
46+
47+ class MultipleRendersFound (Exception ):
48+ pass
49+
50+
3951class CodeplainAPI :
4052
4153 def __init__ (self , api_key ):
@@ -49,7 +61,13 @@ def api_url(self):
4961 def api_url (self , value ):
5062 self ._api_url = value
5163
52- def post_request (self , endpoint_url , headers , payload ):
64+ def _extend_payload_with_run_state (self , payload : dict , run_state : RunState ):
65+ run_state .increment_call_count ()
66+ payload ["render_state" ] = run_state .to_dict ()
67+
68+ def post_request (self , endpoint_url , headers , payload , run_state : Optional [RunState ]):
69+ if run_state is not None :
70+ self ._extend_payload_with_run_state (payload , run_state )
5371 response = requests .post (endpoint_url , headers = headers , json = payload )
5472
5573 try :
@@ -83,6 +101,12 @@ def post_request(self, endpoint_url, headers, payload):
83101 if response_json ["error_code" ] == "LinkMustHaveTextSpecified" :
84102 raise LinkMustHaveTextSpecified (response_json ["message" ])
85103
104+ if response_json ["error_code" ] == "NoRenderFound" :
105+ raise NoRenderFound (response_json ["message" ])
106+
107+ if response_json ["error_code" ] == "MultipleRendersFound" :
108+ raise MultipleRendersFound (response_json ["message" ])
109+
86110 response .raise_for_status ()
87111
88112 return response_json
@@ -106,9 +130,16 @@ def get_plain_source_tree(self, plain_source, loaded_templates):
106130
107131 payload = {"plain_source" : plain_source , "loaded_templates" : loaded_templates }
108132
109- return self .post_request (endpoint_url , headers , payload )
133+ return self .post_request (endpoint_url , headers , payload , None )
110134
111- def render_functional_requirement (self , frid , plain_source_tree , linked_resources , existing_files_content ):
135+ def render_functional_requirement (
136+ self ,
137+ frid ,
138+ plain_source_tree ,
139+ linked_resources ,
140+ existing_files_content ,
141+ run_state : RunState ,
142+ ):
112143 """
113144 Renders the content of a functional requirement based on the provided ID,
114145 plain source tree, and existing files' content.
@@ -138,9 +169,17 @@ def render_functional_requirement(self, frid, plain_source_tree, linked_resource
138169 "existing_files_content" : existing_files_content ,
139170 }
140171
141- return self .post_request (endpoint_url , headers , payload )
172+ return self .post_request (endpoint_url , headers , payload , run_state )
142173
143- def fix_unittests_issue (self , frid , plain_source_tree , linked_resources , existing_files_content , unittests_issue ):
174+ def fix_unittests_issue (
175+ self ,
176+ frid ,
177+ plain_source_tree ,
178+ linked_resources ,
179+ existing_files_content ,
180+ unittests_issue ,
181+ run_state : RunState ,
182+ ):
144183 endpoint_url = f"{ self .api_url } /fix_unittests_issue"
145184 headers = {"X-API-Key" : self .api_key , "Content-Type" : "application/json" }
146185
@@ -152,9 +191,9 @@ def fix_unittests_issue(self, frid, plain_source_tree, linked_resources, existin
152191 "unittests_issue" : unittests_issue ,
153192 }
154193
155- return self .post_request (endpoint_url , headers , payload )
194+ return self .post_request (endpoint_url , headers , payload , run_state )
156195
157- def refactor_source_files_if_needed (self , frid , files_to_check , existing_files_content ):
196+ def refactor_source_files_if_needed (self , frid , files_to_check , existing_files_content , run_state : RunState ):
158197 endpoint_url = f"{ self .api_url } /refactor_source_files_if_needed"
159198 headers = {"X-API-Key" : self .api_key , "Content-Type" : "application/json" }
160199
@@ -164,10 +203,16 @@ def refactor_source_files_if_needed(self, frid, files_to_check, existing_files_c
164203 "existing_files_content" : existing_files_content ,
165204 }
166205
167- return self .post_request (endpoint_url , headers , payload )
206+ return self .post_request (endpoint_url , headers , payload , run_state )
168207
169208 def render_conformance_tests (
170- self , frid , functional_requirement_id , plain_source_tree , linked_resources , existing_files_content
209+ self ,
210+ frid ,
211+ functional_requirement_id ,
212+ plain_source_tree ,
213+ linked_resources ,
214+ existing_files_content ,
215+ run_state : RunState ,
171216 ):
172217 endpoint_url = f"{ self .api_url } /render_conformance_tests"
173218 headers = {"X-API-Key" : self .api_key , "Content-Type" : "application/json" }
@@ -180,9 +225,15 @@ def render_conformance_tests(
180225 "existing_files_content" : existing_files_content ,
181226 }
182227
183- return self .post_request (endpoint_url , headers , payload )
228+ return self .post_request (endpoint_url , headers , payload , run_state )
184229
185- def generate_folder_name_from_functional_requirement (self , frid , functional_requirement , existing_folder_names ):
230+ def generate_folder_name_from_functional_requirement (
231+ self ,
232+ frid ,
233+ functional_requirement ,
234+ existing_folder_names ,
235+ run_state : RunState ,
236+ ):
186237 endpoint_url = f"{ self .api_url } /generate_folder_name_from_functional_requirement"
187238 headers = {"X-API-Key" : self .api_key , "Content-Type" : "application/json" }
188239
@@ -192,7 +243,7 @@ def generate_folder_name_from_functional_requirement(self, frid, functional_requ
192243 "existing_folder_names" : existing_folder_names ,
193244 }
194245
195- return self .post_request (endpoint_url , headers , payload )
246+ return self .post_request (endpoint_url , headers , payload , run_state )
196247
197248 def fix_conformance_tests_issue (
198249 self ,
@@ -206,6 +257,7 @@ def fix_conformance_tests_issue(
206257 acceptance_tests ,
207258 conformance_tests_issue ,
208259 implementation_fix_count ,
260+ run_state : RunState ,
209261 ):
210262 endpoint_url = f"{ self .api_url } /fix_conformance_tests_issue"
211263 headers = {"X-API-Key" : self .api_key , "Content-Type" : "application/json" }
@@ -225,7 +277,7 @@ def fix_conformance_tests_issue(
225277 if acceptance_tests is not None :
226278 payload ["acceptance_tests" ] = acceptance_tests
227279
228- return self .post_request (endpoint_url , headers , payload )
280+ return self .post_request (endpoint_url , headers , payload , run_state )
229281
230282 def render_acceptance_tests (
231283 self ,
@@ -235,6 +287,7 @@ def render_acceptance_tests(
235287 existing_files_content ,
236288 conformance_tests_files ,
237289 acceptance_test ,
290+ run_state : RunState ,
238291 ):
239292 """
240293 Renders acceptance tests based on the provided parameters.
@@ -267,4 +320,4 @@ def render_acceptance_tests(
267320 "acceptance_test" : acceptance_test ,
268321 }
269322
270- return self .post_request (endpoint_url , headers , payload )
323+ return self .post_request (endpoint_url , headers , payload , run_state )
0 commit comments