1- # from typing import Optional, Dict
2- # from osbot_utils.type_safe.Type_Safe import Type_Safe
3- # from osbot_fast_api.api.Fast_API import Fast_API
4- # from osbot_fast_api.api.contracts.Contract__Extractor import Contract__Extractor
5- # from osbot_fast_api.api.contracts.Client__Generator__AST import Client__Generator__AST
6- # from osbot_fast_api.api.contracts.Schema__Service__Contract import Schema__Service__Contract
7- #
8- #
9- # class Fast_API__Client__Generator(Type_Safe):
10- # fast_api : Fast_API # Fast_API instance to generate client for
11- #
12- # def extract_contract(self) -> Schema__Service__Contract: # Extract service contract from Fast_API instance
13- #
14- # extractor = Contract__Extractor (fast_api=self.fast_api)
15- # return extractor.extract_contract()
16- #
17- # def generate_client(self, client_name: Optional[str] = None # Optional client class name
18- # ) -> Dict[str, str]: # Generate client code from Fast_API instance
19- # # Returns dictionary of filename -> code content
20- # # Extract contract
21- # contract = self.extract_contract()
22- # # Generate client code
23- # generator = Client__Generator__AST(contract = contract ,
24- # client_name = client_name )
25- #
26- # return generator.generate_client_files()
27- #
28- # def save_client_files(self, output_dir : str , # Directory to save files to
29- # client_name : Optional[str] = None # Optional client class name
30- # ): # Generate and save client files to directory
31- #
32- # from pathlib import Path
33- # import os
34- # # Generate client code
35- # files = self.generate_client(client_name)
36- # # Create output directory
37- # output_path = Path(output_dir)
38- # output_path.mkdir(parents=True, exist_ok=True)
39- # # Save each file
40- # for file_path, content in files.items():
41- # file_full_path = output_path / file_path
42- # # Create subdirectories if needed
43- # file_full_path.parent.mkdir(parents=True, exist_ok=True)
44- # # Save file
45- # with open(file_full_path, 'w') as f:
46- # f.write(content)
47- #
48- # return list(files.keys())
49- #
50- # def print_client_summary(self): # Print summary of what would be generated
51- #
52- # contract = self.extract_contract()
53- #
54- # print(f"Service: {contract.service_name} v{contract.version}")
55- # print(f"Modules: {len(contract.modules)}")
56- # print(f"Total Endpoints: {len(contract.endpoints)}")
57- # print()
58- #
59- # for module in contract.modules:
60- # print(f" Module '{module.module_name}':")
61- # print(f" Classes: {', '.join(module.route_classes)}")
62- # print(f" Endpoints: {len(module.endpoints)}")
63- #
64- # for endpoint in module.endpoints[:3]: # Show first 3 endpoints
65- # print(f" - {endpoint.method} {endpoint.path_pattern} ({endpoint.route_method})")
66- #
67- # if len(module.endpoints) > 3:
68- # print(f" ... and {len(module.endpoints) - 3} more")
69- # print()
70- #
71- #
72- # # Add method to Fast_API class
73- # def generate_client(self, output_dir : Optional[str] = None , # Optional directory to save files
74- # client_name : Optional[str] = None # Optional name for the client
75- # ) -> Dict[str, str]: # Generate client code for this Fast_API service
76- # # Args:
77- # # output_dir: Optional directory to save files to
78- # # client_name: Optional name for the client (defaults to service name)
79- # # Returns:
80- # # Dictionary of filename -> code content
81- #
82- # generator = Fast_API__Client__Generator(fast_api=self)
83- #
84- # if output_dir: # Save to files and return filenames
85- # filenames = generator.save_client_files(output_dir, client_name)
86- # return {name: f"Saved to {output_dir}/{name}" for name in filenames}
87- # else: # Return generated code
88- # return generator.generate_client(client_name)
89- #
90- # # Monkey-patch the method onto Fast_API class
91- # # This allows any Fast_API instance to generate a client
92- # Fast_API.generate_client = generate_client
1+ from typing import Optional , Dict
2+ from osbot_fast_api . client . Client__Generator__AST import Client__Generator__AST
3+ from osbot_fast_api .client . Fast_API__Contract__Extractor import Fast_API__Contract__Extractor
4+ from osbot_fast_api .client . schemas . Schema__Service__Contract import Schema__Service__Contract
5+ from osbot_utils . type_safe . Type_Safe import Type_Safe
6+ from osbot_fast_api .api .Fast_API import Fast_API
7+
8+
9+ class Fast_API__Client__Generator (Type_Safe ):
10+ fast_api : Fast_API # Fast_API instance to generate client for
11+
12+ def extract_contract (self ) -> Schema__Service__Contract : # Extract service contract from Fast_API instance
13+
14+ extractor = Fast_API__Contract__Extractor (fast_api = self .fast_api )
15+ return extractor .extract_contract ()
16+
17+ def generate_client (self , client_name : Optional [str ] = None # Optional client class name
18+ ) -> Dict [str , str ]: # Generate client code from Fast_API instance
19+ # Returns dictionary of filename -> code content
20+ # Extract contract
21+ contract = self .extract_contract ()
22+ # Generate client code
23+ generator = Client__Generator__AST (contract = contract ,
24+ client_name = client_name )
25+
26+ return generator .generate_client_files ()
27+
28+ def save_client_files (self , output_dir : str , # Directory to save files to
29+ client_name : Optional [str ] = None # Optional client class name
30+ ): # Generate and save client files to directory
31+
32+ from pathlib import Path
33+ import os
34+ # Generate client code
35+ files = self .generate_client (client_name )
36+ # Create output directory
37+ output_path = Path (output_dir )
38+ output_path .mkdir (parents = True , exist_ok = True )
39+ # Save each file
40+ for file_path , content in files .items ():
41+ file_full_path = output_path / file_path
42+ # Create subdirectories if needed
43+ file_full_path .parent .mkdir (parents = True , exist_ok = True )
44+ # Save file
45+ with open (file_full_path , 'w' ) as f :
46+ f .write (content )
47+
48+ return list (files .keys ())
49+
50+ def print_client_summary (self ): # Print summary of what would be generated
51+
52+ contract = self .extract_contract ()
53+
54+ print (f"Service: { contract .service_name } v{ contract .version } " )
55+ print (f"Modules: { len (contract .modules )} " )
56+ print (f"Total Endpoints: { len (contract .endpoints )} " )
57+ print ()
58+
59+ for module in contract .modules :
60+ print (f" Module '{ module .module_name } ':" )
61+ print (f" Classes: { ', ' .join (module .route_classes )} " )
62+ print (f" Endpoints: { len (module .endpoints )} " )
63+
64+ for endpoint in module .endpoints [:3 ]: # Show first 3 endpoints
65+ print (f" - { endpoint .method } { endpoint .path_pattern } ({ endpoint .route_method } )" )
66+
67+ if len (module .endpoints ) > 3 :
68+ print (f" ... and { len (module .endpoints ) - 3 } more" )
69+ print ()
70+
71+
72+ # Add method to Fast_API class
73+ def generate_client (self , output_dir : Optional [str ] = None , # Optional directory to save files
74+ client_name : Optional [str ] = None # Optional name for the client
75+ ) -> Dict [str , str ]: # Generate client code for this Fast_API service
76+ # Args:
77+ # output_dir: Optional directory to save files to
78+ # client_name: Optional name for the client (defaults to service name)
79+ # Returns:
80+ # Dictionary of filename -> code content
81+
82+ generator = Fast_API__Client__Generator (fast_api = self )
83+
84+ if output_dir : # Save to files and return filenames
85+ filenames = generator .save_client_files (output_dir , client_name )
86+ return {name : f"Saved to { output_dir } /{ name } " for name in filenames }
87+ else : # Return generated code
88+ return generator .generate_client (client_name )
89+
90+ # Monkey-patch the method onto Fast_API class
91+ # This allows any Fast_API instance to generate a client
92+ Fast_API .generate_client = generate_client
0 commit comments