def load_clients(self, path=None, apis=[]): """Generate client libraries for the given apis, without starting an api server""" if not path: raise Exception("Missing path to api swagger files") if type(apis) is not list: raise Exception("'apis' should be a list of api names") if len(apis) == 0: raise Exception( "'apis' is an empty list - Expected at least one api name") for api_name in apis: api_path = os.path.join(path, '%s.yaml' % api_name) if not os.path.isfile(api_path): raise Exception("Cannot find swagger specification at %s" % api_path) log.info("Loading api %s from %s" % (api_name, api_path)) ApiPool.add( api_name, yaml_path=api_path, timeout=self.timeout, error_callback=self.error_callback, formats=self.formats, do_persist=False, local=False, ) return self
def start(self, serve=[]): """Load all apis, either as local apis served by the flask app, or as remote apis to be called from whithin the app's endpoints, then start the app server""" # Check arguments if type(serve) is str: serve = [serve] elif type(serve) is list: pass else: raise Exception( "'serve' should be an api name or a list of api names") if len(serve) == 0: raise Exception("You must specify at least one api to serve") for api_name in serve: if api_name not in self.apis: raise Exception( "Can't find %s.yaml (swagger file) in the api directory %s" % (api_name, self.path_apis)) app = self.app app.secret_key = os.urandom(24) # Initialize JWT config conf = get_config() if hasattr(conf, 'jwt_secret'): log.info( "Set JWT parameters to issuer=%s audience=%s secret=%s***" % ( conf.jwt_issuer, conf.jwt_audience, conf.jwt_secret[0:8], )) # Always serve the ping api serve.append('ping') # Let's compress returned data when possible compress = Compress() compress.init_app(app) # All apis that are not served locally are not persistent not_persistent = [] for api_name in self.apis.keys(): if api_name in serve: pass else: not_persistent.append(api_name) # Now load those apis into the ApiPool for api_name, api_path in self.apis.items(): host = None port = None if api_name in serve: # We are serving this api locally: override the host:port specified in the swagger spec host = self.host port = self.port do_persist = True if api_name not in not_persistent else False local = True if api_name in serve else False log.info("Loading api %s from %s (persist: %s)" % (api_name, api_path, do_persist)) ApiPool.add( api_name, yaml_path=api_path, timeout=self.timeout, error_callback=self.error_callback, formats=self.formats, do_persist=do_persist, host=host, port=port, local=local, ) ApiPool.merge() # Now spawn flask routes for all endpoints for api_name in self.apis.keys(): if api_name in serve: log.info("Spawning api %s" % api_name) api = getattr(ApiPool, api_name) # Spawn api and wrap every endpoint in a crash handler that # catches replies and reports errors api.spawn_api(app, decorator=generate_crash_handler_decorator( self.error_decorator)) log.debug("Argv is [%s]" % ' '.join(sys.argv)) if 'celery' in sys.argv[0].lower(): # This code is loading in a celery server - Don't start the actual flask app. log.info("Running in a Celery worker - Not starting the Flask app") return if os.path.basename(sys.argv[0]) == 'gunicorn': # Gunicorn takes care of spawning workers log.info("Running in Gunicorn - Not starting the Flask app") return # Debug mode is the default when not running via gunicorn app.debug = self.debug app.run(host='0.0.0.0', port=self.port)