2525 import yaml
2626except ImportError :
2727 yaml = None
28+ # noinspection PyPackageRequirements
2829import pystache
2930
31+ # noinspection PyUnresolvedReferences,PyPackageRequirements
3032from swagger_python_codegen import __version__
3133
3234THISDIR = Path (__file__ ).resolve ().parent
@@ -167,7 +169,7 @@ def __init__(self, settings, params):
167169 raise TypeError (f"Input file '{ self .input_file } ' exists, but you have no Python YAML support" ) from exc
168170
169171 # Apply any specified fixes to Swagger specification.
170- if 'http ' in self .params .fix :
172+ if 'http_response ' in self .params .fix :
171173 self .swagger_spec = self .fix_response_http_codes (self .swagger_spec )
172174
173175 # Parse the top-level API info from the Swagger spec.
@@ -402,15 +404,20 @@ def generate(self):
402404 for template_name , template_dest in self .template_dests .items ():
403405 template_dest_path = self .output_base .joinpath (template_dest )
404406 self .template_firsts = {}
407+ custom_renderer = getattr (self , f'render_{ template_name } ' , None )
405408
406409 # Simple file template: render content directly using simple renderer,
407410 template_vars = self .resolve_vars (self .template_vars [template_name ])
408411 if not template_dest .endswith ('/' ):
409412 if not self .check_output_overwrite (template_dest_path ):
410413 continue
411- output = self .renderer .render (self .templates [template_name ], {** self .common_vars , ** template_vars })
412- os .makedirs (template_dest_path .parent , exist_ok = True )
413- template_dest_path .write_text (output , encoding = 'utf-8' )
414+ template_vars = {** self .common_vars , ** template_vars }
415+ if callable (custom_renderer ):
416+ custom_renderer (template_name , template_dest_path , template_vars )
417+ else :
418+ output = self .renderer .render (self .templates [template_name ], template_vars )
419+ os .makedirs (template_dest_path .parent , exist_ok = True )
420+ template_dest_path .write_text (output , encoding = 'utf-8' )
414421 PRINT (f"Generated '{ template_name } ' to '{ template_dest } '" )
415422 continue
416423
@@ -424,7 +431,6 @@ def generate(self):
424431 os .makedirs (template_dest_path , exist_ok = True )
425432
426433 # Invoke custom renderer for each directory template.
427- custom_renderer = getattr (self , f'render_{ template_name } ' , None )
428434 if not callable (custom_renderer ):
429435 raise NotImplementedError (f"ERROR: { custom_renderer } () not implemented; cannot continue" )
430436 custom_renderer (template_name , template_dest_path , template_vars )
@@ -628,6 +634,24 @@ def render_api(self, template_name, template_dest_path, template_vars): # noqa:
628634 raise RuntimeError (f"ERROR: Failure rendering template '{ template_name } '"
629635 f" (resource group '{ group_name } '): { exc } " ) from exc
630636
637+ def render_api_client (self , template_name , template_dest_path , template_vars ):
638+ """ Renders the API client module for the SDK. """
639+ content = self .renderer .render (self .templates [template_name ], template_vars )
640+ if 'thread_pool' in self .params .fix :
641+ if 'def pool' in content : # (newer template, using property for pool member)
642+ setter = indent (dedent ("""\
643+ @pool.setter
644+ def pool(self, _pool):
645+ self._pool = _pool
646+ """ ), 4 * ' ' )
647+ content = re .sub (r'(return *self._pool.*\n)' , f"\\ 1\n { setter } " , content )
648+ else : # (legacy, using attribute for pool member)
649+ content = re .sub (r'\n( +)self\.pool *= *ThreadPool' ,
650+ "from unittest.mock import Mock\n \\ 1self.\\ 2pool = Mock" ,
651+ content )
652+ os .makedirs (template_dest_path .parent , exist_ok = True )
653+ template_dest_path .write_text (content , encoding = 'utf-8' )
654+
631655 def render_model_doc (self , template_name , template_dest_path , template_vars ):
632656 """ Renders the SDK documentation for each defined model in the API. """
633657 PRINT_VERBOSE ("--- Processing API models for documentation generation:" )
@@ -791,7 +815,8 @@ class MultiRawFormatter(argparse.RawTextHelpFormatter,
791815 PRINT (__version__ )
792816 sys .exit (0 )
793817
794- desc , epilog = __doc__ .split ('\n \n ' , maxsplit = 1 )
818+ desc , * epilog = __doc__ .split ('\n \n ' , maxsplit = 1 )
819+ epilog = epilog [0 ] if epilog else ''
795820 parser = argparse .ArgumentParser (description = '\n ' .join (wrap (desc , width = 80 )).strip (),
796821 fromfile_prefix_chars = '@' ,
797822 epilog = f"\n Generator Properties:\n { indent (properties_table , ' ' )} \n \n "
@@ -859,8 +884,11 @@ class MultiRawFormatter(argparse.RawTextHelpFormatter,
859884 help = dedent ("""\
860885 Specifies which optional fixes to apply before or during
861886 generation; PROBLEM may be any or all of:
862- http => makes HTTP response code specifications
863- consistent within input OpenAPI spec""" ))
887+ http_response => makes HTTP response code specifications
888+ consistent within input OpenAPI spec
889+ thread_pool => allows 'multiprocessing.ThreadPool'
890+ instance in SDK API client object to be
891+ modifiable (for client object copying)""" ))
864892 parser .add_argument ('--generate' ,
865893 metavar = 'FEATURE' , nargs = '+' , action = 'append' , default = [],
866894 help = dedent ("""\
@@ -912,6 +940,7 @@ def _parse_multi_params(_param_name, _multi_params):
912940
913941 params .import_mappings = _parse_multi_params ('import-mappings' , params .import_mappings )
914942 params .generate = _parse_multi_params ('generate' , params .generate )
943+ params .fix = _parse_multi_params ('fix' , params .fix )
915944
916945 # noinspection PyArgumentList
917946 return ParsedArgs (params , unknown_args , settings )
0 commit comments