codeplain 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. codeplain-0.1.0.dist-info/METADATA +142 -0
  2. codeplain-0.1.0.dist-info/RECORD +51 -0
  3. codeplain-0.1.0.dist-info/WHEEL +5 -0
  4. codeplain-0.1.0.dist-info/entry_points.txt +2 -0
  5. codeplain-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. codeplain-0.1.0.dist-info/top_level.txt +36 -0
  7. codeplain_REST_api.py +370 -0
  8. config/__init__.py +2 -0
  9. config/system_config.yaml +27 -0
  10. file_utils.py +316 -0
  11. git_utils.py +304 -0
  12. hash_key.py +29 -0
  13. plain2code.py +218 -0
  14. plain2code_arguments.py +286 -0
  15. plain2code_console.py +107 -0
  16. plain2code_exceptions.py +45 -0
  17. plain2code_nodes.py +108 -0
  18. plain2code_read_config.py +74 -0
  19. plain2code_state.py +75 -0
  20. plain2code_utils.py +56 -0
  21. plain_spec.py +360 -0
  22. render_machine/actions/analyze_specification_ambiguity.py +50 -0
  23. render_machine/actions/base_action.py +19 -0
  24. render_machine/actions/commit_conformance_tests_changes.py +46 -0
  25. render_machine/actions/commit_implementation_code_changes.py +22 -0
  26. render_machine/actions/create_dist.py +26 -0
  27. render_machine/actions/exit_with_error.py +22 -0
  28. render_machine/actions/fix_conformance_test.py +121 -0
  29. render_machine/actions/fix_unit_tests.py +57 -0
  30. render_machine/actions/prepare_repositories.py +50 -0
  31. render_machine/actions/prepare_testing_environment.py +30 -0
  32. render_machine/actions/refactor_code.py +48 -0
  33. render_machine/actions/render_conformance_tests.py +169 -0
  34. render_machine/actions/render_functional_requirement.py +69 -0
  35. render_machine/actions/run_conformance_tests.py +44 -0
  36. render_machine/actions/run_unit_tests.py +38 -0
  37. render_machine/actions/summarize_conformance_tests.py +34 -0
  38. render_machine/code_renderer.py +50 -0
  39. render_machine/conformance_test_helpers.py +68 -0
  40. render_machine/implementation_code_helpers.py +20 -0
  41. render_machine/render_context.py +280 -0
  42. render_machine/render_types.py +36 -0
  43. render_machine/render_utils.py +92 -0
  44. render_machine/state_machine_config.py +408 -0
  45. render_machine/states.py +52 -0
  46. render_machine/triggers.py +27 -0
  47. standard_template_library/__init__.py +1 -0
  48. standard_template_library/golang-console-app-template.plain +36 -0
  49. standard_template_library/python-console-app-template.plain +32 -0
  50. standard_template_library/typescript-react-app-template.plain +22 -0
  51. system_config.py +49 -0
@@ -0,0 +1,142 @@
1
+ Metadata-Version: 2.4
2
+ Name: codeplain
3
+ Version: 0.1.0
4
+ Summary: Transform plain language specifications into working code
5
+ Classifier: Environment :: Console
6
+ Classifier: Intended Audience :: Developers
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Topic :: Software Development :: Code Generators
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: python-liquid2==0.3.0
16
+ Requires-Dist: mistletoe==1.3.0
17
+ Requires-Dist: langchain==1.0.8
18
+ Requires-Dist: langchain-core==1.2.3
19
+ Requires-Dist: langchain-openai==1.0.3
20
+ Requires-Dist: langchain-anthropic==1.1.0
21
+ Requires-Dist: langchain-aws==1.0.0
22
+ Requires-Dist: langchain-cerebras==0.8.0
23
+ Requires-Dist: langchain-google-genai==4.1.2
24
+ Requires-Dist: langchain-ollama==1.0.0
25
+ Requires-Dist: requests==2.32.3
26
+ Requires-Dist: langsmith==0.4.4
27
+ Requires-Dist: rich==14.2.0
28
+ Requires-Dist: tiktoken==0.12.0
29
+ Requires-Dist: PyYAML==6.0.2
30
+ Requires-Dist: gitpython==3.1.42
31
+ Requires-Dist: lizard==1.18.0
32
+ Requires-Dist: textual==1.0.0
33
+ Requires-Dist: SQLAlchemy==2.0.36
34
+ Requires-Dist: psycopg2==2.9.10
35
+ Requires-Dist: python-dotenv==1.1.0
36
+ Requires-Dist: transitions==0.9.3
37
+ Requires-Dist: cryptography==46.0.1
38
+ Provides-Extra: dev
39
+ Requires-Dist: pytest==8.3.5; extra == "dev"
40
+ Requires-Dist: flake8==7.0.0; extra == "dev"
41
+ Requires-Dist: black==24.2.0; extra == "dev"
42
+ Requires-Dist: isort==5.13.2; extra == "dev"
43
+ Requires-Dist: flake8-bugbear==24.12.12; extra == "dev"
44
+ Requires-Dist: flake8-unused-arguments==0.0.13; extra == "dev"
45
+ Requires-Dist: flake8-eradicate==1.5.0; extra == "dev"
46
+ Requires-Dist: pep8-naming==0.15.1; extra == "dev"
47
+ Requires-Dist: mypy==1.11.2; extra == "dev"
48
+ Dynamic: license-file
49
+
50
+ # Codeplain plain2code renderer
51
+
52
+ Render ***plain source to software code using the Codeplain API.
53
+
54
+ ## Codeplain.ai - Code Generation as a Service
55
+
56
+ Codeplain is a platform that generates software code using large language models based on requirements you specify in ***plain specification language.
57
+
58
+ Schematic overview of the Codeplain's code generation service
59
+
60
+ <img src="resources/codeplain_overview.png">
61
+
62
+ ### Abstracting Away Code Generation Complexity with ***plain
63
+
64
+
65
+ ***plain is a novel specification language that helps abstracting away complexity of using large language models for code generation.
66
+
67
+ An example application in ***plain
68
+
69
+ <img src="resources/plain_example.png" width="70%" height="70%">
70
+
71
+
72
+ ## Getting started
73
+
74
+ ### Prerequisites
75
+
76
+
77
+ #### System requirements
78
+
79
+ To run the plain2code client, you need Python 3.11 or a later version.
80
+
81
+ **Windows users:** Please install WSL (Windows Subsystem for Linux) as this is currently the supported environment for running plain code on Windows.
82
+
83
+ #### Authorization - Codeplain API Key
84
+
85
+ We are using Codeplain API Key to authorize requests to the Codeplain API. To get your Codeplain API Key, please contact Codeplain.ai support at support@codeplain.ai.
86
+
87
+ In order to generate code, you need to export the following environment variable:
88
+
89
+ ```bash
90
+ export CODEPLAIN_API_KEY="your_actual_api_key_here"
91
+ ```
92
+
93
+ ### Installation Steps
94
+
95
+ 1. Clone this repository
96
+ 2. Set your Codeplain API key as an environment variable:
97
+ ```
98
+ export CODEPLAIN_API_KEY=your_api_key_here
99
+ ```
100
+ 3. (Recommended) Create and activate a virtual environment:
101
+ ```bash
102
+ python -m venv .venv
103
+ source .venv/bin/activate
104
+ ```
105
+ 4. Install required libraries
106
+ ```
107
+ pip install -r requirements.txt
108
+ ```
109
+
110
+ ### Quick Start
111
+
112
+ After completing the installation steps above, you can immediately test the system with a simple "Hello World" example:
113
+
114
+ - Change to the example folder and run the example:
115
+ ```
116
+ cd examples/example_hello_world_python
117
+ python ../../plain2code.py hello_world_python.plain
118
+ ```
119
+
120
+ *Note: Rendering will take a few minutes to complete.*
121
+
122
+ - The system will generate a Python application in the `build` directory. You can run it with:
123
+ ```
124
+ cd build
125
+ python hello_world.py
126
+ ```
127
+
128
+ ## Additional Resources
129
+
130
+ ### Examples and Sample Projects
131
+
132
+ - See the [examples](examples) folder for sample projects in Golang, Python, and React.
133
+ - For example application how to implement task manager in ***plain see [example-task-manager](https://github.com/Codeplain-ai/example-task-manager) repository.
134
+ - For example application how to implement SaaS connectors in ***plain see [example-saas-connectors](https://github.com/Codeplain-ai/example-saas-connectors) repository.
135
+
136
+ ### Documentation
137
+
138
+ - For more details on the ***plain format, see the [***plain language specification](docs/plain_language_specification.md).
139
+ - For step-by-step instructions for creating your first ***plain project see the [Kickstart your ***plain project](docs/starting_a_plain_project_from_scratch.md).
140
+ - For complete CLI documentation and usage examples, see [plain2code CLI documentation](docs/plain2code_cli.md).
141
+
142
+
@@ -0,0 +1,51 @@
1
+ codeplain_REST_api.py,sha256=C0PoV3xgXXH4GUBJYMq-dKnxtt3eKSykPgND31TNATo,14781
2
+ file_utils.py,sha256=MaHDvn-a5fB2_D0kvAk1MGxqs5Povke2NIA-WLjdo_s,11387
3
+ git_utils.py,sha256=vLDVRek9nhYdAR4IRp_M8WNn-pyYjVjrIxNfEXEij2E,10153
4
+ hash_key.py,sha256=lMKgKpOhPeC4UpFf9e7eCNK20FEaDsXTCJ8j3eCWidE,837
5
+ plain2code.py,sha256=rvP0-GDgr9F05dyAsYTelgn2kza3pLK9ODSWG9PE5kw,8098
6
+ plain2code_arguments.py,sha256=wMIbDVjzXZnrkXnbhBWc9Vz7ddQCPIm_wg56Wp_aado,11040
7
+ plain2code_console.py,sha256=08TWADO9bmwmN6oMfLsjDKF54EIPc3mPlipFGy3Gwsk,3778
8
+ plain2code_exceptions.py,sha256=UTFovKObkYuIOfknZcEISL06_V5JavnAJsR4rcTubsI,717
9
+ plain2code_nodes.py,sha256=Om624mfb5MB1Z09c0Zqtb9G1gGkUY9x-v2hzAf3A2gw,3818
10
+ plain2code_read_config.py,sha256=QnpbW_Bi9LzDIOubM5x7fVXH1HgiFL3-5Oa_O1EUoE4,2449
11
+ plain2code_state.py,sha256=K1U9EoaGHboWEf5SVhSx3sN-ZvCEcAztV0q9dpj-2Zw,2570
12
+ plain2code_utils.py,sha256=gxH8i-XHK-K9s9reBNose0UKYrH7oLjSsaEKMpLS1g0,2471
13
+ plain_spec.py,sha256=SwjhdYuMJzwtF70ti7r5tVXogGbzvutu4U42u0AuKdU,13457
14
+ system_config.py,sha256=mgHLn-CRHLO9Y9vKyI_eFBreY_YhFad-ctZgBYp-rIg,1777
15
+ codeplain-0.1.0.dist-info/licenses/LICENSE,sha256=wsFi5dpbJurnRNfBj8q2RCcF3ryrmdRIfxc3lPcmc4c,1069
16
+ config/__init__.py,sha256=iHrUksORYKKYsPhE2D_zvZ5tV7mfFAp16c_Cp38hT7A,38
17
+ config/system_config.yaml,sha256=bB5Th5jxgXFyaIvceUPID1ReebMMXsyMibV4gtu9sWQ,1148
18
+ render_machine/code_renderer.py,sha256=kHS_8uZEgQhygGvw0GBoA-V2nW8lIpoF1GJgyRw8oNk,2072
19
+ render_machine/conformance_test_helpers.py,sha256=6Ru7Dh24SLNIKWfz_sP5hE_EmWpvk6nfgN1T1yaCZus,2887
20
+ render_machine/implementation_code_helpers.py,sha256=XhjbQRn2mhfIXs1QioqFlopRfzUrY3U9DsFq38IFvic,816
21
+ render_machine/render_context.py,sha256=OTlSwIqgt7UzMytSjQqqpAZTwjUE0l-eyCXJRpjii8E,13944
22
+ render_machine/render_types.py,sha256=Ke1LzVXAY5XvJwMcY97C7gZniuRAgJRSCv4Flcfn-ig,1156
23
+ render_machine/render_utils.py,sha256=ImqoIcGy9s4y3IF6BuAFOWZ4_10UB2CKBE6zf_pLd2M,4302
24
+ render_machine/state_machine_config.py,sha256=9aQOcWesI-fQ9_BpicpQ3flzSTln18QBVsr_ZHi_3T0,26109
25
+ render_machine/states.py,sha256=GvjGMYKYURKzTS7W2B8HOeDGt43z2AoKPcUv3FDnK9Q,1973
26
+ render_machine/triggers.py,sha256=GarwIYPY6ZZzVdRF7yXLB54tofr08NpFZfp5DH6AOuI,1331
27
+ render_machine/actions/analyze_specification_ambiguity.py,sha256=UsDQeOZI4l58rwZ9yjPtgB5-erz55HJvcjMrjMObV2I,2608
28
+ render_machine/actions/base_action.py,sha256=vVzMp-LanrZyq-jamHyWaQxpRl-pLqtTdtiEzUBhfyE,534
29
+ render_machine/actions/commit_conformance_tests_changes.py,sha256=3W-AnUFoukbN5U70PqsRwiL_wIoFwqsz6lM2TDoSy6k,2265
30
+ render_machine/actions/commit_implementation_code_changes.py,sha256=5A55hESZGs-XXEZSPk7KvTeUmJWTOyG9IOIiuDEsv4Y,791
31
+ render_machine/actions/create_dist.py,sha256=1t-DIZhtbajaLdtF05vsv4-MEuZpOxhBMX0EJ-TeCe0,1019
32
+ render_machine/actions/exit_with_error.py,sha256=R0J1HPQtgHrVr8U5_r5uckXYzcuBFmsras5Avjh1Ra4,854
33
+ render_machine/actions/fix_conformance_test.py,sha256=X8HWjMp8b0J2thB1rWqAefZkDTsViBUJi5BA65uui5A,6158
34
+ render_machine/actions/fix_unit_tests.py,sha256=muabQEaWwzCoONjfGCMbODKZt5-xPLhfAAMD3O2AIs8,2448
35
+ render_machine/actions/prepare_repositories.py,sha256=kjc12Q6FArn3Wg_r-SYioW6sZSbN0LSbpI_b4pFMXQY,2109
36
+ render_machine/actions/prepare_testing_environment.py,sha256=J6GMclP07k7LuHrp5P7LOb4UJ7M3PAT1EWWLgKnAtHQ,1236
37
+ render_machine/actions/refactor_code.py,sha256=NoPv04RWedFL0gehiOnBSGD-cy6DFEz0smeRO23f_Ts,2116
38
+ render_machine/actions/render_conformance_tests.py,sha256=AvzdM6yV79kSLAV6m3VB3JYrBnOS0OXsV3G9SXK8Uw4,8034
39
+ render_machine/actions/render_functional_requirement.py,sha256=Yq4r_LLmHLT1_SSK5uCuNWQV9baHzHA_bxNQJqNe58w,3389
40
+ render_machine/actions/run_conformance_tests.py,sha256=DslNg5i4utlEkd4bmtDmTNxDye11n3juWzf6E95afMI,1900
41
+ render_machine/actions/run_unit_tests.py,sha256=7xMiMrjW1yOJavI97huA4dj5hpNroxDZh2ASx4rcIoI,1561
42
+ render_machine/actions/summarize_conformance_tests.py,sha256=mFU-GhOBGqhwDIMYlQtPUi4aUr-GJYPNXHeiK9U561g,1611
43
+ standard_template_library/__init__.py,sha256=LtsHl0c3VV46DUInIqyOw4KKVoxKEMOx8dAZpMXtAXc,43
44
+ standard_template_library/golang-console-app-template.plain,sha256=aPg2uhoNUFryVXzs0a2QjY82-uzftOgtrXNjDBAM8WU,1396
45
+ standard_template_library/python-console-app-template.plain,sha256=5kqK5kErQ-Pa46iT3LVIYyBw68B8__CS-S4MoXkBx7Q,1432
46
+ standard_template_library/typescript-react-app-template.plain,sha256=6JXLqQja17M7NbDEmk6pRltaD2m00OoDo6pJxuiv1Do,465
47
+ codeplain-0.1.0.dist-info/METADATA,sha256=rJvrDgTtVlE6PoSfj7fCkdr9oGcOxJQC8jYJ-Y6WOfw,4974
48
+ codeplain-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ codeplain-0.1.0.dist-info/entry_points.txt,sha256=oDZkBqu9WhtZApb_K6ia8-fn9aojwmAsgnKELceX5T4,46
50
+ codeplain-0.1.0.dist-info/top_level.txt,sha256=wNGviii6Ojj3wNiGASr-QbTS8Xkiyux_nMeQJGL_OTE,536
51
+ codeplain-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ codeplain = plain2code:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Codeplain.ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,36 @@
1
+ code_complexity
2
+ codeplain
3
+ codeplain_REST_api
4
+ codeplain_constants
5
+ codeplain_local_api
6
+ codeplain_models
7
+ codeplain_types
8
+ codeplain_utils
9
+ config
10
+ content_extractor
11
+ event_bus
12
+ file_utils
13
+ git_utils
14
+ hash_key
15
+ llm
16
+ llm_exceptions
17
+ llm_handler
18
+ llm_selector
19
+ plain2code
20
+ plain2code_arguments
21
+ plain2code_console
22
+ plain2code_events
23
+ plain2code_exceptions
24
+ plain2code_nodes
25
+ plain2code_read_config
26
+ plain2code_state
27
+ plain2code_tui
28
+ plain2code_utils
29
+ plain_file
30
+ plain_spec
31
+ render_cache
32
+ render_machine
33
+ spinner
34
+ standard_template_library
35
+ system_config
36
+ tui_components
codeplain_REST_api.py ADDED
@@ -0,0 +1,370 @@
1
+ import time
2
+ from typing import Optional
3
+
4
+ import requests
5
+ from requests.exceptions import ConnectionError, RequestException, Timeout
6
+
7
+ import plain2code_exceptions
8
+ from plain2code_state import RunState
9
+
10
+ MAX_RETRIES = 4
11
+ RETRY_DELAY = 3
12
+
13
+
14
+ class CodeplainAPI:
15
+
16
+ def __init__(self, api_key, console):
17
+ self.api_key = api_key
18
+ self.console = console
19
+
20
+ @property
21
+ def api_url(self):
22
+ return self._api_url
23
+
24
+ @api_url.setter
25
+ def api_url(self, value):
26
+ self._api_url = value
27
+
28
+ def _extend_payload_with_run_state(self, payload: dict, run_state: RunState):
29
+ run_state.increment_call_count()
30
+ payload["render_state"] = run_state.to_dict()
31
+
32
+ def post_request(self, endpoint_url, headers, payload, run_state: Optional[RunState]): # noqa: C901
33
+ if run_state is not None:
34
+ self._extend_payload_with_run_state(payload, run_state)
35
+
36
+ retry_delay = RETRY_DELAY
37
+ for attempt in range(MAX_RETRIES + 1):
38
+ try:
39
+ response = requests.post(endpoint_url, headers=headers, json=payload)
40
+
41
+ try:
42
+ response_json = response.json()
43
+ except requests.exceptions.JSONDecodeError as e:
44
+ print(f"Failed to decode JSON response: {e}. Response text: {response.text}")
45
+ raise
46
+
47
+ if response.status_code == requests.codes.bad_request and "error_code" in response_json:
48
+ if response_json["error_code"] == "FunctionalRequirementTooComplex":
49
+ raise plain2code_exceptions.FunctionalRequirementTooComplex(
50
+ response_json["message"], response_json.get("proposed_breakdown")
51
+ )
52
+
53
+ if response_json["error_code"] == "ConflictingRequirements":
54
+ raise plain2code_exceptions.ConflictingRequirements(response_json["message"])
55
+
56
+ if response_json["error_code"] == "CreditBalanceTooLow":
57
+ raise plain2code_exceptions.CreditBalanceTooLow(response_json["message"])
58
+
59
+ if response_json["error_code"] == "LLMInternalError":
60
+ raise plain2code_exceptions.LLMInternalError(response_json["message"])
61
+
62
+ if response_json["error_code"] == "MissingResource":
63
+ raise plain2code_exceptions.MissingResource(response_json["message"])
64
+
65
+ if response_json["error_code"] == "PlainSyntaxError":
66
+ raise plain2code_exceptions.PlainSyntaxError(response_json["message"])
67
+
68
+ if response_json["error_code"] == "OnlyRelativeLinksAllowed":
69
+ raise plain2code_exceptions.OnlyRelativeLinksAllowed(response_json["message"])
70
+
71
+ if response_json["error_code"] == "LinkMustHaveTextSpecified":
72
+ raise plain2code_exceptions.LinkMustHaveTextSpecified(response_json["message"])
73
+
74
+ if response_json["error_code"] == "NoRenderFound":
75
+ raise plain2code_exceptions.NoRenderFound(response_json["message"])
76
+
77
+ if response_json["error_code"] == "MultipleRendersFound":
78
+ raise plain2code_exceptions.MultipleRendersFound(response_json["message"])
79
+
80
+ response.raise_for_status()
81
+ return response_json
82
+
83
+ except (ConnectionError, Timeout, RequestException) as e:
84
+ if attempt < MAX_RETRIES:
85
+ self.console.info(f"Connection error on attempt {attempt + 1}/{MAX_RETRIES + 1}: {e}")
86
+ self.console.info(f"Retrying in {retry_delay} seconds...")
87
+ time.sleep(retry_delay)
88
+ # Exponential backoff
89
+ retry_delay *= 2
90
+ else:
91
+ self.console.error(f"Max retries ({MAX_RETRIES}) exceeded. Last error: {e}")
92
+ raise RequestException(
93
+ f"Connection error: Unable to reach the Codeplain API at {self.api_url}. Please try again or contact support."
94
+ )
95
+
96
+ def get_plain_source_tree(self, plain_source, loaded_templates, run_state: RunState):
97
+ """
98
+ Builds plain source tree from the given plain text source in Markdown format.
99
+
100
+ Args:
101
+ plain_source (str): A string containing the plain text source to be parsed.
102
+ loaded_templates (dict): A dictionary containing the loaded templates.
103
+
104
+ Returns:
105
+ dict: A plain source tree.
106
+
107
+ Raises:
108
+ Exception: If parsing of plain_source fails.
109
+ """
110
+ endpoint_url = f"{self.api_url}/plain_source_tree"
111
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
112
+
113
+ payload = {"plain_source": plain_source, "loaded_templates": loaded_templates}
114
+
115
+ return self.post_request(endpoint_url, headers, payload, run_state)
116
+
117
+ def render_functional_requirement(
118
+ self,
119
+ frid,
120
+ plain_source_tree,
121
+ linked_resources,
122
+ existing_files_content,
123
+ run_state: RunState,
124
+ ):
125
+ """
126
+ Renders the content of a functional requirement based on the provided ID,
127
+ plain source tree, and existing files' content.
128
+
129
+ Args:
130
+ frid (str): The unique identifier for the functional requirement to be rendered.
131
+ plain_source_tree (dict): A dictionary containing the plain source tree.
132
+ linked_resources (dict): A dictionary where the keys represent resource names
133
+ and the values are the content of those resources.
134
+ existing_files_content (dict): A dictionary where the keys represent code base
135
+ filenames and the values are the content of those files.
136
+
137
+ Returns:
138
+ str: A string containing the rendered functional requirement, formatted
139
+ appropriately based on the inputs.
140
+
141
+ Raises:
142
+ ValueError: If the frid is invalid or the necessary plain source tree is not valid.
143
+ """
144
+ endpoint_url = f"{self.api_url}/render_functional_requirement"
145
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
146
+
147
+ payload = {
148
+ "frid": frid,
149
+ "plain_source_tree": plain_source_tree,
150
+ "linked_resources": linked_resources,
151
+ "existing_files_content": existing_files_content,
152
+ }
153
+
154
+ return self.post_request(endpoint_url, headers, payload, run_state)
155
+
156
+ def fix_unittests_issue(
157
+ self,
158
+ frid,
159
+ plain_source_tree,
160
+ linked_resources,
161
+ existing_files_content,
162
+ unittests_issue,
163
+ run_state: RunState,
164
+ ):
165
+ endpoint_url = f"{self.api_url}/fix_unittests_issue"
166
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
167
+
168
+ payload = {
169
+ "frid": frid,
170
+ "plain_source_tree": plain_source_tree,
171
+ "linked_resources": linked_resources,
172
+ "existing_files_content": existing_files_content,
173
+ "unittests_issue": unittests_issue,
174
+ "unittest_batch_id": run_state.unittest_batch_id,
175
+ }
176
+
177
+ return self.post_request(endpoint_url, headers, payload, run_state)
178
+
179
+ def refactor_source_files_if_needed(self, frid, files_to_check, existing_files_content, run_state: RunState):
180
+ endpoint_url = f"{self.api_url}/refactor_source_files_if_needed"
181
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
182
+
183
+ payload = {
184
+ "frid": frid,
185
+ "files_to_check": list(files_to_check),
186
+ "existing_files_content": existing_files_content,
187
+ }
188
+
189
+ return self.post_request(endpoint_url, headers, payload, run_state)
190
+
191
+ def render_conformance_tests(
192
+ self,
193
+ frid,
194
+ functional_requirement_id,
195
+ plain_source_tree,
196
+ linked_resources,
197
+ existing_files_content,
198
+ conformance_tests_folder_name,
199
+ conformance_tests_json,
200
+ all_acceptance_tests,
201
+ run_state: RunState,
202
+ ):
203
+ endpoint_url = f"{self.api_url}/render_conformance_tests"
204
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
205
+
206
+ payload = {
207
+ "frid": frid,
208
+ "functional_requirement_id": functional_requirement_id,
209
+ "plain_source_tree": plain_source_tree,
210
+ "linked_resources": linked_resources,
211
+ "existing_files_content": existing_files_content,
212
+ "conformance_tests_folder_name": conformance_tests_folder_name,
213
+ "conformance_tests_json": conformance_tests_json,
214
+ "all_acceptance_tests": all_acceptance_tests,
215
+ }
216
+
217
+ response = self.post_request(endpoint_url, headers, payload, run_state)
218
+ return response["patched_response_files"], response["conformance_tests_plan_summary_string"]
219
+
220
+ def generate_folder_name_from_functional_requirement(
221
+ self,
222
+ frid,
223
+ functional_requirement,
224
+ existing_folder_names,
225
+ run_state: RunState,
226
+ ):
227
+ endpoint_url = f"{self.api_url}/generate_folder_name_from_functional_requirement"
228
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
229
+
230
+ payload = {
231
+ "frid": frid,
232
+ "functional_requirement": functional_requirement,
233
+ "existing_folder_names": existing_folder_names,
234
+ }
235
+
236
+ return self.post_request(endpoint_url, headers, payload, run_state)
237
+
238
+ def fix_conformance_tests_issue(
239
+ self,
240
+ frid,
241
+ functional_requirement_id,
242
+ plain_source_tree,
243
+ linked_resources,
244
+ existing_files_content,
245
+ code_diff,
246
+ conformance_tests_files,
247
+ acceptance_tests,
248
+ conformance_tests_issue,
249
+ implementation_fix_count,
250
+ conformance_tests_folder_name,
251
+ current_testing_frid_high_level_implementation_plan: Optional[str],
252
+ run_state: RunState,
253
+ ):
254
+ endpoint_url = f"{self.api_url}/fix_conformance_tests_issue"
255
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
256
+
257
+ payload = {
258
+ "frid": frid,
259
+ "functional_requirement_id": functional_requirement_id,
260
+ "plain_source_tree": plain_source_tree,
261
+ "linked_resources": linked_resources,
262
+ "existing_files_content": existing_files_content,
263
+ "code_diff": code_diff,
264
+ "conformance_tests_files": conformance_tests_files,
265
+ "conformance_tests_issue": conformance_tests_issue,
266
+ "implementation_fix_count": implementation_fix_count,
267
+ "conformance_tests_folder_name": conformance_tests_folder_name,
268
+ "current_testing_frid_high_level_implementation_plan": current_testing_frid_high_level_implementation_plan,
269
+ }
270
+
271
+ if acceptance_tests is not None:
272
+ payload["acceptance_tests"] = acceptance_tests
273
+
274
+ return self.post_request(endpoint_url, headers, payload, run_state)
275
+
276
+ def render_acceptance_tests(
277
+ self,
278
+ frid,
279
+ plain_source_tree,
280
+ linked_resources,
281
+ existing_files_content,
282
+ conformance_tests_files,
283
+ acceptance_test,
284
+ run_state: RunState,
285
+ ):
286
+ """
287
+ Renders acceptance tests based on the provided parameters.
288
+
289
+ Args:
290
+ frid (str): The unique identifier for the functional requirement.
291
+ plain_source_tree (dict): A dictionary containing the plain source tree.
292
+ linked_resources (dict): A dictionary where the keys represent resource names
293
+ and the values are the content of those resources.
294
+ existing_files_content (dict): A dictionary where the keys represent code base
295
+ filenames and the values are the content of those files.
296
+ conformance_tests_files (dict): A dictionary containing conformance test files.
297
+ acceptance_test (dict): A dictionary containing acceptance test information.
298
+
299
+ Returns:
300
+ dict: The rendered acceptance tests.
301
+
302
+ Raises:
303
+ Exception: If the request fails or returns an error.
304
+ """
305
+ endpoint_url = f"{self.api_url}/render_acceptance_tests"
306
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
307
+
308
+ payload = {
309
+ "frid": frid,
310
+ "plain_source_tree": plain_source_tree,
311
+ "linked_resources": linked_resources,
312
+ "existing_files_content": existing_files_content,
313
+ "conformance_tests_files": conformance_tests_files,
314
+ "acceptance_test": acceptance_test,
315
+ }
316
+
317
+ return self.post_request(endpoint_url, headers, payload, run_state)
318
+
319
+ def analyze_rendering(
320
+ self,
321
+ frid,
322
+ plain_source_tree,
323
+ linked_resources,
324
+ existing_files_content,
325
+ implementation_code_diff,
326
+ fixed_implementation_code_diff,
327
+ run_state: RunState,
328
+ ):
329
+ endpoint_url = f"{self.api_url}/analyze_rendering"
330
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
331
+
332
+ payload = {
333
+ "frid": frid,
334
+ "plain_source_tree": plain_source_tree,
335
+ "linked_resources": linked_resources,
336
+ "existing_files_content": existing_files_content,
337
+ "implementation_code_diff": implementation_code_diff,
338
+ "fixed_implementation_code_diff": fixed_implementation_code_diff,
339
+ }
340
+
341
+ return self.post_request(endpoint_url, headers, payload, run_state)
342
+
343
+ def finish_functional_requirement(self, frid, run_state: RunState):
344
+ endpoint_url = f"{self.api_url}/finish_functional_requirement"
345
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
346
+
347
+ payload = {
348
+ "frid": frid,
349
+ }
350
+
351
+ return self.post_request(endpoint_url, headers, payload, run_state)
352
+
353
+ def summarize_finished_conformance_tests(
354
+ self,
355
+ frid,
356
+ plain_source_tree,
357
+ linked_resources,
358
+ conformance_test_files_content,
359
+ run_state: RunState,
360
+ ):
361
+ endpoint_url = f"{self.api_url}/summarize_finished_conformance_tests"
362
+ headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
363
+ payload = {
364
+ "frid": frid,
365
+ "plain_source_tree": plain_source_tree,
366
+ "linked_resources": linked_resources,
367
+ "conformance_test_files_content": conformance_test_files_content,
368
+ }
369
+
370
+ return self.post_request(endpoint_url, headers, payload, run_state)
config/__init__.py ADDED
@@ -0,0 +1,2 @@
1
+ # Configuration files for plain2code
2
+
@@ -0,0 +1,27 @@
1
+ system_requirements:
2
+ timeout:
3
+ command: timeout
4
+ error_message: |
5
+ Error: Required system command 'timeout' is not available.
6
+ This command is needed to enforce time limits on test execution.
7
+
8
+ To install the timeout command:
9
+ - On Linux: Install coreutils package
10
+ - Debian/Ubuntu: sudo apt-get install coreutils
11
+ - CentOS/RHEL: sudo yum install coreutils
12
+ - Fedora: sudo dnf install coreutils
13
+ - On macOS:
14
+ - Using Homebrew: brew install coreutils
15
+ - Using MacPorts: port install coreutils
16
+ - On Windows: Use Windows Subsystem for Linux (WSL), Cygwin, or Git Bash
17
+
18
+ error_messages:
19
+ template_not_found:
20
+ message: |
21
+ The required template could not be found. Templates are searched in the following order (highest to lowest precedence):
22
+
23
+ 1. The directory containing your .plain file
24
+ 2. The directory specified by --template-dir (if provided)
25
+ 3. The built-in 'standard_template_library' directory
26
+
27
+ Please ensure that the missing template exists in one of these locations, or specify the correct --template-dir if using custom templates.