1010from pathlib import Path
1111
1212import libcst as cst
13-
1413from openapi_client .arazzo .emit import emit_arazzo_json
1514from openapi_client .arazzo .parse import parse_arazzo_json , resolve_source_descriptions
1615from openapi_client .arazzo_models import Arazzo
4948from openapi_client .sqlalchemy_cdd .emit import emit_sqlalchemy
5049from openapi_client .sqlalchemy_cdd .parse import parse_sqlalchemy_cdd
5150from openapi_client .sync import sync_dir
52- from openapi_client .tests .emit import emit_tests
51+ from openapi_client .tests .emit import emit_api_tests , emit_tests
5352from openapi_client .tests .emit_arazzo_tests import emit_arazzo_tests_code
5453from openapi_client .tests .emit_server_tests import emit_server_tests
5554from openapi_client .tests .parse import extract_tests_from_ast
@@ -104,9 +103,7 @@ def get_version() -> str:
104103 return "0.0.4"
105104
106105
107- def apply_env_vars_to_parser (
108- parser : argparse .ArgumentParser , prefix : str = "CDD_"
109- ) -> None :
106+ def apply_env_vars_to_parser (parser : argparse .ArgumentParser , prefix : str = "CDD_" ) -> None :
110107 """Recursively set argparse default values from environment variables.
111108
112109 Args:
@@ -177,28 +174,19 @@ def generate_from_openapi(
177174 src_dir .mkdir (parents = True , exist_ok = True )
178175 (src_dir / "__init__.py" ).touch (exist_ok = True )
179176
180- (src_dir / "client.py" ).write_text (
181- generator .generate_code (), encoding = "utf-8"
182- )
177+ (src_dir / "client.py" ).write_text (generator .generate_code (), encoding = "utf-8" )
183178 if spec .components and spec .components .schemas :
184- (src_dir / "models.py" ).write_text (
185- emit_models_module (spec .components .schemas ), encoding = "utf-8"
186- )
179+ (src_dir / "models.py" ).write_text (emit_models_module (spec .components .schemas ), encoding = "utf-8" )
187180
188- (src_dir / "openapi.snapshot.json" ).write_text (
189- emit_openapi_json (spec , indent = 2 ), encoding = "utf-8"
190- )
181+ (src_dir / "openapi.snapshot.json" ).write_text (emit_openapi_json (spec , indent = 2 ), encoding = "utf-8" )
191182
192183 if tests :
193184 test_dir = out_dir / "test"
194185 test_dir .mkdir (parents = True , exist_ok = True )
195186 (test_dir / "__init__.py" ).touch ()
196- (test_dir / "test_client.py" ).write_text (
197- emit_tests (spec , composable = True ).code , encoding = "utf-8"
198- )
199- (test_dir / "mock_server.py" ).write_text (
200- emit_mock_server (spec ).code , encoding = "utf-8"
201- )
187+ (test_dir / "test_client.py" ).write_text (emit_tests (spec , composable = True ).code , encoding = "utf-8" )
188+ (test_dir / "test_api.py" ).write_text (emit_api_tests (spec ).code , encoding = "utf-8" )
189+ (test_dir / "mock_server.py" ).write_text (emit_mock_server (spec ).code , encoding = "utf-8" )
202190 write_generated (emit_dao (spec ), "dao.py" , base_dir = test_dir )
203191 elif subcommand == "to_sdk_cli" :
204192 generator = ClientGenerator (spec )
@@ -207,39 +195,24 @@ def generate_from_openapi(
207195 src_dir .mkdir (parents = True , exist_ok = True )
208196 (src_dir / "__init__.py" ).touch (exist_ok = True )
209197
210- (src_dir / "client.py" ).write_text (
211- generator .generate_code (), encoding = "utf-8"
212- )
198+ (src_dir / "client.py" ).write_text (generator .generate_code (), encoding = "utf-8" )
213199
214200 if spec .components and spec .components .schemas :
215- (src_dir / "models.py" ).write_text (
216- emit_models_module (spec .components .schemas ), encoding = "utf-8"
217- )
201+ (src_dir / "models.py" ).write_text (emit_models_module (spec .components .schemas ), encoding = "utf-8" )
218202
219- (src_dir / "cli_main.py" ).write_text (
220- emit_cli_sdk_cdd (spec ), encoding = "utf-8"
221- )
203+ (src_dir / "cli_main.py" ).write_text (emit_cli_sdk_cdd (spec ), encoding = "utf-8" )
222204 if mcp :
223- (src_dir / "mcp_server.py" ).write_text (
224- emit_mcp_server (spec ), encoding = "utf-8"
225- )
226- (src_dir / "mcp_sse_server.py" ).write_text (
227- emit_mcp_sse_server (spec ), encoding = "utf-8"
228- )
229- (src_dir / "mcp_adapter.py" ).write_text (
230- emit_mcp_adapter (spec ), encoding = "utf-8"
231- )
205+ (src_dir / "mcp_server.py" ).write_text (emit_mcp_server (spec ), encoding = "utf-8" )
206+ (src_dir / "mcp_sse_server.py" ).write_text (emit_mcp_sse_server (spec ), encoding = "utf-8" )
207+ (src_dir / "mcp_adapter.py" ).write_text (emit_mcp_adapter (spec ), encoding = "utf-8" )
232208
233209 if tests :
234210 test_dir = out_dir / "test"
235211 test_dir .mkdir (parents = True , exist_ok = True )
236212 (test_dir / "__init__.py" ).touch ()
237- (test_dir / "test_client.py" ).write_text (
238- emit_tests (spec , composable = True ).code , encoding = "utf-8"
239- )
240- (test_dir / "mock_server.py" ).write_text (
241- emit_mock_server (spec ).code , encoding = "utf-8"
242- )
213+ (test_dir / "test_client.py" ).write_text (emit_tests (spec , composable = True ).code , encoding = "utf-8" )
214+ (test_dir / "test_api.py" ).write_text (emit_api_tests (spec ).code , encoding = "utf-8" )
215+ (test_dir / "mock_server.py" ).write_text (emit_mock_server (spec ).code , encoding = "utf-8" )
243216 write_generated (emit_dao (spec ), "dao.py" , base_dir = test_dir )
244217 elif subcommand == "to_server" :
245218 (out_dir / "__init__.py" ).touch (exist_ok = True )
@@ -317,9 +290,7 @@ def generate_from_arazzo(
317290 specs .append (
318291 (
319292 spec_path .parent ,
320- parse_arazzo_json (
321- spec_path .read_text (encoding = "utf-8" ), spec_path .parent
322- ),
293+ parse_arazzo_json (spec_path .read_text (encoding = "utf-8" ), spec_path .parent ),
323294 )
324295 )
325296 elif input_dir :
@@ -338,59 +309,39 @@ def generate_from_arazzo(
338309 src_dir = out_dir / "src"
339310 src_dir .mkdir (parents = True , exist_ok = True )
340311 (src_dir / "__init__.py" ).touch (exist_ok = True )
341- (src_dir / "workflows.py" ).write_text (
342- emit_workflows_code (spec , sources ), encoding = "utf-8"
343- )
344- (src_dir / "arazzo.snapshot.json" ).write_text (
345- emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8"
346- )
312+ (src_dir / "workflows.py" ).write_text (emit_workflows_code (spec , sources ), encoding = "utf-8" )
313+ (src_dir / "arazzo.snapshot.json" ).write_text (emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8" )
347314 if tests :
348315 test_dir = out_dir / "test"
349316 test_dir .mkdir (parents = True , exist_ok = True )
350317 (test_dir / "__init__.py" ).touch (exist_ok = True )
351- (test_dir / "test_workflows.py" ).write_text (
352- emit_arazzo_tests_code (spec ), encoding = "utf-8"
353- )
318+ (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
354319 elif subcommand == "to_sdk_cli" :
355320 src_dir = out_dir / "src"
356321 src_dir .mkdir (parents = True , exist_ok = True )
357322 (src_dir / "__init__.py" ).touch (exist_ok = True )
358- (src_dir / "workflows.py" ).write_text (
359- emit_workflows_code (spec , sources ), encoding = "utf-8"
360- )
361- (src_dir / "cli_workflows.py" ).write_text (
362- emit_arazzo_cli_code (spec ), encoding = "utf-8"
363- )
364- (src_dir / "arazzo.snapshot.json" ).write_text (
365- emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8"
366- )
323+ (src_dir / "workflows.py" ).write_text (emit_workflows_code (spec , sources ), encoding = "utf-8" )
324+ (src_dir / "cli_workflows.py" ).write_text (emit_arazzo_cli_code (spec ), encoding = "utf-8" )
325+ (src_dir / "arazzo.snapshot.json" ).write_text (emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8" )
367326 if tests :
368327 test_dir = out_dir / "test"
369328 test_dir .mkdir (parents = True , exist_ok = True )
370329 (test_dir / "__init__.py" ).touch (exist_ok = True )
371- (test_dir / "test_workflows.py" ).write_text (
372- emit_arazzo_tests_code (spec ), encoding = "utf-8"
373- )
330+ (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
374331 elif subcommand == "to_tests" :
375332 test_dir = out_dir / "test"
376333 test_dir .mkdir (parents = True , exist_ok = True )
377334 (test_dir / "__init__.py" ).touch (exist_ok = True )
378- (test_dir / "test_workflows.py" ).write_text (
379- emit_arazzo_tests_code (spec ), encoding = "utf-8"
380- )
335+ (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
381336 else :
382337 routes_dir = out_dir / "routes"
383338 routes_dir .mkdir (parents = True , exist_ok = True )
384339 (routes_dir / "__init__.py" ).touch (exist_ok = True )
385- (routes_dir / "workflows.py" ).write_text (
386- emit_fastapi_arazzo_routes (spec ), encoding = "utf-8"
387- )
340+ (routes_dir / "workflows.py" ).write_text (emit_fastapi_arazzo_routes (spec ), encoding = "utf-8" )
388341 test_dir = out_dir / "tests"
389342 test_dir .mkdir (parents = True , exist_ok = True )
390343 (test_dir / "__init__.py" ).touch (exist_ok = True )
391- (test_dir / "test_workflows.py" ).write_text (
392- emit_arazzo_tests_code (spec ), encoding = "utf-8"
393- )
344+ (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
394345
395346 if not no_installable_package :
396347 scaffold_package (out_dir , is_server = (subcommand == "to_server" ))
@@ -486,11 +437,7 @@ def generate_to_openapi(input_path: str | Path, output_path: str | Path) -> None
486437 if not models_py .exists ():
487438 models_py = in_path / "models.py"
488439
489- models_dir = (
490- in_path / "src" / "models"
491- if (in_path / "src" / "models" ).is_dir ()
492- else in_path / "models"
493- )
440+ models_dir = in_path / "src" / "models" if (in_path / "src" / "models" ).is_dir () else in_path / "models"
494441
495442 mock_py = in_path / "test" / "mock_server.py"
496443 if not mock_py .exists ():
@@ -556,29 +503,21 @@ def generate_to_openapi(input_path: str | Path, output_path: str | Path) -> None
556503
557504def main () -> None :
558505 """CLI entrypoint."""
559- parser = argparse .ArgumentParser (
560- description = "Compiler Driven Development (CDD) compiler and transpiler."
561- )
506+ parser = argparse .ArgumentParser (description = "Compiler Driven Development (CDD) compiler and transpiler." )
562507 parser .add_argument (
563508 "--version" ,
564509 action = "version" ,
565510 version = get_version (),
566511 )
567512 subparsers = parser .add_subparsers (dest = "command" )
568513
569- from_openapi_parser = subparsers .add_parser (
570- "from_openapi" , help = "Generate code from an OpenAPI specification."
571- )
514+ from_openapi_parser = subparsers .add_parser ("from_openapi" , help = "Generate code from an OpenAPI specification." )
572515
573- from_openapi_subparsers = from_openapi_parser .add_subparsers (
574- dest = "from_openapi_command" , required = True
575- )
516+ from_openapi_subparsers = from_openapi_parser .add_subparsers (dest = "from_openapi_command" , required = True )
576517
577518 for subcmd in ["to_sdk" , "to_sdk_cli" , "to_server" ]:
578519 if subcmd == "to_sdk_cli" :
579- help_text = (
580- "Generate a client SDK with a CLI from an OpenAPI specification."
581- )
520+ help_text = "Generate a client SDK with a CLI from an OpenAPI specification."
582521 elif subcmd == "to_sdk" :
583522 help_text = "Generate a client SDK from an OpenAPI specification."
584523 else :
@@ -653,12 +592,8 @@ def main() -> None:
653592 help = "Output file or directory path" ,
654593 )
655594
656- from_arazzo_parser = subparsers .add_parser (
657- "from_arazzo" , help = "Generate code from an Arazzo 1.1.0 specification."
658- )
659- from_arazzo_subparsers = from_arazzo_parser .add_subparsers (
660- dest = "from_arazzo_command" , required = True
661- )
595+ from_arazzo_parser = subparsers .add_parser ("from_arazzo" , help = "Generate code from an Arazzo 1.1.0 specification." )
596+ from_arazzo_subparsers = from_arazzo_parser .add_subparsers (dest = "from_arazzo_command" , required = True )
662597 for ar_subcmd in ["to_sdk" , "to_sdk_cli" , "to_server" , "to_tests" ]:
663598 ar_p = from_arazzo_subparsers .add_parser (
664599 ar_subcmd ,
@@ -759,30 +694,18 @@ def main() -> None:
759694 required = True ,
760695 help = "Path or URL to the OpenAPI specification." ,
761696 )
762- docs_parser .add_argument (
763- "--no-imports" , action = "store_true" , help = "Omit the imports field."
764- )
765- docs_parser .add_argument (
766- "--no-wrapping" , action = "store_true" , help = "Omit the wrapper fields."
767- )
768- docs_parser .add_argument (
769- "-o" , "--output" , type = str , help = "Output file or directory path."
770- )
697+ docs_parser .add_argument ("--no-imports" , action = "store_true" , help = "Omit the imports field." )
698+ docs_parser .add_argument ("--no-wrapping" , action = "store_true" , help = "Omit the wrapper fields." )
699+ docs_parser .add_argument ("-o" , "--output" , type = str , help = "Output file or directory path." )
771700
772701 server_parser = subparsers .add_parser (
773702 "serve_json_rpc" ,
774703 help = "Expose CLI interface as a JSON-RPC server." ,
775704 )
776- server_parser .add_argument (
777- "-p" , "--port" , type = int , default = 8080 , help = "Port to listen on"
778- )
779- server_parser .add_argument (
780- "-l" , "--listen" , type = str , default = "127.0.0.1" , help = "Address to listen on"
781- )
705+ server_parser .add_argument ("-p" , "--port" , type = int , default = 8080 , help = "Port to listen on" )
706+ server_parser .add_argument ("-l" , "--listen" , type = str , default = "127.0.0.1" , help = "Address to listen on" )
782707
783- subparsers .add_parser (
784- "mcp" , help = "Run the Model Context Protocol server via stdio."
785- )
708+ subparsers .add_parser ("mcp" , help = "Run the Model Context Protocol server via stdio." )
786709
787710 apply_env_vars_to_parser (parser )
788711 args = parser .parse_args ()
@@ -792,9 +715,7 @@ def main() -> None:
792715 sys .exit (0 )
793716
794717 if args .command == "sync" :
795- sync_dir (
796- args .input , getattr (args , "truth" , None ), getattr (args , "output" , None )
797- )
718+ sync_dir (args .input , getattr (args , "truth" , None ), getattr (args , "output" , None ))
798719 elif args .command == "from_openapi" :
799720 subcmd = args .from_openapi_command
800721 if not args .input and not getattr (args , "input_dir" , None ):
0 commit comments