1010from pathlib import Path
1111
1212import libcst as cst
13+
1314from openapi_client .arazzo .emit import emit_arazzo_json
1415from openapi_client .arazzo .parse import parse_arazzo_json , resolve_source_descriptions
1516from openapi_client .arazzo_models import Arazzo
@@ -103,7 +104,9 @@ def get_version() -> str:
103104 return "0.0.4"
104105
105106
106- def apply_env_vars_to_parser (parser : argparse .ArgumentParser , prefix : str = "CDD_" ) -> None :
107+ def apply_env_vars_to_parser (
108+ parser : argparse .ArgumentParser , prefix : str = "CDD_"
109+ ) -> None :
107110 """Recursively set argparse default values from environment variables.
108111
109112 Args:
@@ -174,19 +177,31 @@ def generate_from_openapi(
174177 src_dir .mkdir (parents = True , exist_ok = True )
175178 (src_dir / "__init__.py" ).touch (exist_ok = True )
176179
177- (src_dir / "client.py" ).write_text (generator .generate_code (), encoding = "utf-8" )
180+ (src_dir / "client.py" ).write_text (
181+ generator .generate_code (), encoding = "utf-8"
182+ )
178183 if spec .components and spec .components .schemas :
179- (src_dir / "models.py" ).write_text (emit_models_module (spec .components .schemas ), encoding = "utf-8" )
184+ (src_dir / "models.py" ).write_text (
185+ emit_models_module (spec .components .schemas ), encoding = "utf-8"
186+ )
180187
181- (src_dir / "openapi.snapshot.json" ).write_text (emit_openapi_json (spec , indent = 2 ), encoding = "utf-8" )
188+ (src_dir / "openapi.snapshot.json" ).write_text (
189+ emit_openapi_json (spec , indent = 2 ), encoding = "utf-8"
190+ )
182191
183192 if tests :
184193 test_dir = out_dir / "test"
185194 test_dir .mkdir (parents = True , exist_ok = True )
186195 (test_dir / "__init__.py" ).touch ()
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" )
196+ (test_dir / "test_client.py" ).write_text (
197+ emit_tests (spec , composable = True ).code , encoding = "utf-8"
198+ )
199+ (test_dir / "test_api.py" ).write_text (
200+ emit_api_tests (spec ).code , encoding = "utf-8"
201+ )
202+ (test_dir / "mock_server.py" ).write_text (
203+ emit_mock_server (spec ).code , encoding = "utf-8"
204+ )
190205 write_generated (emit_dao (spec ), "dao.py" , base_dir = test_dir )
191206 elif subcommand == "to_sdk_cli" :
192207 generator = ClientGenerator (spec )
@@ -195,24 +210,42 @@ def generate_from_openapi(
195210 src_dir .mkdir (parents = True , exist_ok = True )
196211 (src_dir / "__init__.py" ).touch (exist_ok = True )
197212
198- (src_dir / "client.py" ).write_text (generator .generate_code (), encoding = "utf-8" )
213+ (src_dir / "client.py" ).write_text (
214+ generator .generate_code (), encoding = "utf-8"
215+ )
199216
200217 if spec .components and spec .components .schemas :
201- (src_dir / "models.py" ).write_text (emit_models_module (spec .components .schemas ), encoding = "utf-8" )
218+ (src_dir / "models.py" ).write_text (
219+ emit_models_module (spec .components .schemas ), encoding = "utf-8"
220+ )
202221
203- (src_dir / "cli_main.py" ).write_text (emit_cli_sdk_cdd (spec ), encoding = "utf-8" )
222+ (src_dir / "cli_main.py" ).write_text (
223+ emit_cli_sdk_cdd (spec ), encoding = "utf-8"
224+ )
204225 if mcp :
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" )
226+ (src_dir / "mcp_server.py" ).write_text (
227+ emit_mcp_server (spec ), encoding = "utf-8"
228+ )
229+ (src_dir / "mcp_sse_server.py" ).write_text (
230+ emit_mcp_sse_server (spec ), encoding = "utf-8"
231+ )
232+ (src_dir / "mcp_adapter.py" ).write_text (
233+ emit_mcp_adapter (spec ), encoding = "utf-8"
234+ )
208235
209236 if tests :
210237 test_dir = out_dir / "test"
211238 test_dir .mkdir (parents = True , exist_ok = True )
212239 (test_dir / "__init__.py" ).touch ()
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" )
240+ (test_dir / "test_client.py" ).write_text (
241+ emit_tests (spec , composable = True ).code , encoding = "utf-8"
242+ )
243+ (test_dir / "test_api.py" ).write_text (
244+ emit_api_tests (spec ).code , encoding = "utf-8"
245+ )
246+ (test_dir / "mock_server.py" ).write_text (
247+ emit_mock_server (spec ).code , encoding = "utf-8"
248+ )
216249 write_generated (emit_dao (spec ), "dao.py" , base_dir = test_dir )
217250 elif subcommand == "to_server" :
218251 (out_dir / "__init__.py" ).touch (exist_ok = True )
@@ -290,7 +323,9 @@ def generate_from_arazzo(
290323 specs .append (
291324 (
292325 spec_path .parent ,
293- parse_arazzo_json (spec_path .read_text (encoding = "utf-8" ), spec_path .parent ),
326+ parse_arazzo_json (
327+ spec_path .read_text (encoding = "utf-8" ), spec_path .parent
328+ ),
294329 )
295330 )
296331 elif input_dir :
@@ -309,39 +344,59 @@ def generate_from_arazzo(
309344 src_dir = out_dir / "src"
310345 src_dir .mkdir (parents = True , exist_ok = True )
311346 (src_dir / "__init__.py" ).touch (exist_ok = True )
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" )
347+ (src_dir / "workflows.py" ).write_text (
348+ emit_workflows_code (spec , sources ), encoding = "utf-8"
349+ )
350+ (src_dir / "arazzo.snapshot.json" ).write_text (
351+ emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8"
352+ )
314353 if tests :
315354 test_dir = out_dir / "test"
316355 test_dir .mkdir (parents = True , exist_ok = True )
317356 (test_dir / "__init__.py" ).touch (exist_ok = True )
318- (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
357+ (test_dir / "test_workflows.py" ).write_text (
358+ emit_arazzo_tests_code (spec ), encoding = "utf-8"
359+ )
319360 elif subcommand == "to_sdk_cli" :
320361 src_dir = out_dir / "src"
321362 src_dir .mkdir (parents = True , exist_ok = True )
322363 (src_dir / "__init__.py" ).touch (exist_ok = True )
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" )
364+ (src_dir / "workflows.py" ).write_text (
365+ emit_workflows_code (spec , sources ), encoding = "utf-8"
366+ )
367+ (src_dir / "cli_workflows.py" ).write_text (
368+ emit_arazzo_cli_code (spec ), encoding = "utf-8"
369+ )
370+ (src_dir / "arazzo.snapshot.json" ).write_text (
371+ emit_arazzo_json (spec , indent = 2 ), encoding = "utf-8"
372+ )
326373 if tests :
327374 test_dir = out_dir / "test"
328375 test_dir .mkdir (parents = True , exist_ok = True )
329376 (test_dir / "__init__.py" ).touch (exist_ok = True )
330- (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
377+ (test_dir / "test_workflows.py" ).write_text (
378+ emit_arazzo_tests_code (spec ), encoding = "utf-8"
379+ )
331380 elif subcommand == "to_tests" :
332381 test_dir = out_dir / "test"
333382 test_dir .mkdir (parents = True , exist_ok = True )
334383 (test_dir / "__init__.py" ).touch (exist_ok = True )
335- (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
384+ (test_dir / "test_workflows.py" ).write_text (
385+ emit_arazzo_tests_code (spec ), encoding = "utf-8"
386+ )
336387 else :
337388 routes_dir = out_dir / "routes"
338389 routes_dir .mkdir (parents = True , exist_ok = True )
339390 (routes_dir / "__init__.py" ).touch (exist_ok = True )
340- (routes_dir / "workflows.py" ).write_text (emit_fastapi_arazzo_routes (spec ), encoding = "utf-8" )
391+ (routes_dir / "workflows.py" ).write_text (
392+ emit_fastapi_arazzo_routes (spec ), encoding = "utf-8"
393+ )
341394 test_dir = out_dir / "tests"
342395 test_dir .mkdir (parents = True , exist_ok = True )
343396 (test_dir / "__init__.py" ).touch (exist_ok = True )
344- (test_dir / "test_workflows.py" ).write_text (emit_arazzo_tests_code (spec ), encoding = "utf-8" )
397+ (test_dir / "test_workflows.py" ).write_text (
398+ emit_arazzo_tests_code (spec ), encoding = "utf-8"
399+ )
345400
346401 if not no_installable_package :
347402 scaffold_package (out_dir , is_server = (subcommand == "to_server" ))
@@ -437,7 +492,11 @@ def generate_to_openapi(input_path: str | Path, output_path: str | Path) -> None
437492 if not models_py .exists ():
438493 models_py = in_path / "models.py"
439494
440- models_dir = in_path / "src" / "models" if (in_path / "src" / "models" ).is_dir () else in_path / "models"
495+ models_dir = (
496+ in_path / "src" / "models"
497+ if (in_path / "src" / "models" ).is_dir ()
498+ else in_path / "models"
499+ )
441500
442501 mock_py = in_path / "test" / "mock_server.py"
443502 if not mock_py .exists ():
@@ -503,21 +562,29 @@ def generate_to_openapi(input_path: str | Path, output_path: str | Path) -> None
503562
504563def main () -> None :
505564 """CLI entrypoint."""
506- parser = argparse .ArgumentParser (description = "Compiler Driven Development (CDD) compiler and transpiler." )
565+ parser = argparse .ArgumentParser (
566+ description = "Compiler Driven Development (CDD) compiler and transpiler."
567+ )
507568 parser .add_argument (
508569 "--version" ,
509570 action = "version" ,
510571 version = get_version (),
511572 )
512573 subparsers = parser .add_subparsers (dest = "command" )
513574
514- from_openapi_parser = subparsers .add_parser ("from_openapi" , help = "Generate code from an OpenAPI specification." )
575+ from_openapi_parser = subparsers .add_parser (
576+ "from_openapi" , help = "Generate code from an OpenAPI specification."
577+ )
515578
516- from_openapi_subparsers = from_openapi_parser .add_subparsers (dest = "from_openapi_command" , required = True )
579+ from_openapi_subparsers = from_openapi_parser .add_subparsers (
580+ dest = "from_openapi_command" , required = True
581+ )
517582
518583 for subcmd in ["to_sdk" , "to_sdk_cli" , "to_server" ]:
519584 if subcmd == "to_sdk_cli" :
520- help_text = "Generate a client SDK with a CLI from an OpenAPI specification."
585+ help_text = (
586+ "Generate a client SDK with a CLI from an OpenAPI specification."
587+ )
521588 elif subcmd == "to_sdk" :
522589 help_text = "Generate a client SDK from an OpenAPI specification."
523590 else :
@@ -592,8 +659,12 @@ def main() -> None:
592659 help = "Output file or directory path" ,
593660 )
594661
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 )
662+ from_arazzo_parser = subparsers .add_parser (
663+ "from_arazzo" , help = "Generate code from an Arazzo 1.1.0 specification."
664+ )
665+ from_arazzo_subparsers = from_arazzo_parser .add_subparsers (
666+ dest = "from_arazzo_command" , required = True
667+ )
597668 for ar_subcmd in ["to_sdk" , "to_sdk_cli" , "to_server" , "to_tests" ]:
598669 ar_p = from_arazzo_subparsers .add_parser (
599670 ar_subcmd ,
@@ -694,18 +765,30 @@ def main() -> None:
694765 required = True ,
695766 help = "Path or URL to the OpenAPI specification." ,
696767 )
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." )
768+ docs_parser .add_argument (
769+ "--no-imports" , action = "store_true" , help = "Omit the imports field."
770+ )
771+ docs_parser .add_argument (
772+ "--no-wrapping" , action = "store_true" , help = "Omit the wrapper fields."
773+ )
774+ docs_parser .add_argument (
775+ "-o" , "--output" , type = str , help = "Output file or directory path."
776+ )
700777
701778 server_parser = subparsers .add_parser (
702779 "serve_json_rpc" ,
703780 help = "Expose CLI interface as a JSON-RPC server." ,
704781 )
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" )
782+ server_parser .add_argument (
783+ "-p" , "--port" , type = int , default = 8080 , help = "Port to listen on"
784+ )
785+ server_parser .add_argument (
786+ "-l" , "--listen" , type = str , default = "127.0.0.1" , help = "Address to listen on"
787+ )
707788
708- subparsers .add_parser ("mcp" , help = "Run the Model Context Protocol server via stdio." )
789+ subparsers .add_parser (
790+ "mcp" , help = "Run the Model Context Protocol server via stdio."
791+ )
709792
710793 apply_env_vars_to_parser (parser )
711794 args = parser .parse_args ()
@@ -715,7 +798,9 @@ def main() -> None:
715798 sys .exit (0 )
716799
717800 if args .command == "sync" :
718- sync_dir (args .input , getattr (args , "truth" , None ), getattr (args , "output" , None ))
801+ sync_dir (
802+ args .input , getattr (args , "truth" , None ), getattr (args , "output" , None )
803+ )
719804 elif args .command == "from_openapi" :
720805 subcmd = args .from_openapi_command
721806 if not args .input and not getattr (args , "input_dir" , None ):
0 commit comments