<s> from collections import OrderedDict <EOL> import inspect <EOL> import operator <EOL> from functools import partial <EOL> from flask import current_app , make_response , json , Response , request <EOL> from six import wraps <EOL> from werkzeug . exceptions import HTTPException <EOL> from werkzeug . wrappers import BaseResponse <EOL> from . exceptions import PotionException <EOL> from . routes import RouteSet , to_camel_case <EOL> from . utils import unpack <EOL> from . resource import Resource , ModelResource <EOL> __all__ = ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> def _make_response ( data , code , headers = None ) : <EOL> settings = { } <EOL> if current_app . debug : <EOL> settings . setdefault ( '<STR_LIT>' , <NUM_LIT:4> ) <EOL> settings . setdefault ( '<STR_LIT>' , True ) <EOL> data = json . dumps ( data , ** settings ) <EOL> resp = make_response ( data , code ) <EOL> resp . headers . extend ( headers or { } ) <EOL> resp . headers [ '<STR_LIT:Content-Type>' ] = '<STR_LIT:application/json>' <EOL> return resp <EOL> class Api ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , app = None , decorators = None , prefix = None , title = None , description = None , default_manager = None ) : <EOL> self . app = app <EOL> self . blueprint = None <EOL> self . prefix = prefix or '<STR_LIT>' <EOL> self . decorators = decorators or [ ] <EOL> self . title = title <EOL> self . description = description <EOL> self . endpoints = set ( ) <EOL> self . resources = { } <EOL> self . views = [ ] <EOL> self . default_manager = None <EOL> if default_manager is None : <EOL> try : <EOL> from flask_potion . contrib . alchemy import SQLAlchemyManager <EOL> self . default_manager = SQLAlchemyManager <EOL> except ImportError : <EOL> pass <EOL> else : <EOL> self . default_manager = default_manager <EOL> if app is not None : <EOL> self . init_app ( app ) <EOL> def init_app ( self , app ) : <EOL> try : <EOL> app . record ( self . _deferred_blueprint_init ) <EOL> except AttributeError : <EOL> self . _init_app ( app ) <EOL> else : <EOL> self . blueprint = app <EOL> def _deferred_blueprint_init ( self , setup_state ) : <EOL> self . prefix = '<STR_LIT>' . join ( ( setup_state . url_prefix or '<STR_LIT>' , self . prefix ) ) <EOL> for resource in self . resources . values ( ) : <EOL> resource . route_prefix = '<STR_LIT>' . join ( ( self . prefix , '<STR_LIT:/>' , resource . meta . name ) ) <EOL> self . _init_app ( setup_state . app ) <EOL> def _init_app ( self , app ) : <EOL> """<STR_LIT>""" <EOL> app . config . setdefault ( '<STR_LIT>' , <NUM_LIT:100> ) <EOL> app . config . setdefault ( '<STR_LIT>' , <NUM_LIT:20> ) <EOL> self . _register_view ( app , <EOL> rule = '<STR_LIT>' . join ( ( self . prefix , '<STR_LIT>' ) ) , <EOL> view_func = self . output ( self . _schema_view ) , <EOL> endpoint = '<STR_LIT>' , <EOL> methods = [ '<STR_LIT:GET>' ] ) <EOL> for route , resource , view_func , endpoint , methods in self . views : <EOL> rule = route . rule_factory ( resource ) <EOL> self . _register_view ( app , rule , view_func , endpoint , methods ) <EOL> app . handle_exception = partial ( self . _exception_handler , app . handle_exception ) <EOL> app . handle_user_exception = partial ( self . _exception_handler , app . handle_user_exception ) <EOL> def _register_view ( self , app , rule , view_func , endpoint , methods ) : <EOL> if self . blueprint : <EOL> endpoint = '<STR_LIT>' . format ( self . blueprint . name , endpoint ) <EOL> app . add_url_rule ( rule , <EOL> view_func = view_func , <EOL> endpoint = endpoint , <EOL> methods = methods ) <EOL> def _exception_handler ( self , original_handler , e ) : <EOL> if isinstance ( e , PotionException ) : <EOL> return e . get_response ( ) <EOL> if not request . path . startswith ( self . prefix ) : <EOL> return original_handler ( e ) <EOL> if isinstance ( e , HTTPException ) : <EOL> return _make_response ( { <EOL> '<STR_LIT:status>' : e . code , <EOL> '<STR_LIT:message>' : e . description <EOL> } , e . code ) <EOL> return original_handler ( e ) <EOL> def output ( self , view ) : <EOL> @ wraps ( view ) <EOL> def wrapper ( * args , ** kwargs ) : <EOL> resp = view ( * args , ** kwargs ) <EOL> if isinstance ( resp , BaseResponse ) : <EOL> return resp <EOL> data , code , headers = unpack ( resp ) <EOL> return _make_response ( data , code , headers ) <EOL> return wrapper <EOL> def _schema_view ( self ) : <EOL> schema = OrderedDict ( ) <EOL> schema [ "<STR_LIT>" ] = "<STR_LIT>" <EOL> if self . title : <EOL> schema [ "<STR_LIT:title>" ] = self . title <EOL> if self . description : <EOL> schema [ "<STR_LIT:description>" ] = self . description <EOL> schema [ "<STR_LIT>" ] = properties = OrderedDict ( [ ] ) <EOL> for name , resource in sorted ( self . resources . items ( ) , key = operator . itemgetter ( <NUM_LIT:0> ) ) : <EOL> resource_schema_rule = resource . routes [ '<STR_LIT>' ] . rule_factory ( resource ) <EOL> properties [ name ] = { "<STR_LIT>" : '<STR_LIT>' . format ( resource_schema_rule ) } <EOL> return OrderedDict ( schema ) , <NUM_LIT:200> , { '<STR_LIT:Content-Type>' : '<STR_LIT>' } <EOL> def add_route ( self , route , resource , endpoint = None , decorator = None ) : <EOL> endpoint = endpoint or '<STR_LIT:_>' . join ( ( resource . meta . name , route . relation ) ) <EOL> methods = [ route . method ] <EOL> rule = route . rule_factory ( resource ) <EOL> view_func = route . view_factory ( endpoint , resource ) <EOL> if decorator : <EOL> view_func = decorator ( view_func ) <EOL> view = self . output ( view_func ) <EOL> for decorator in self . decorators : <EOL> view = decorator ( view ) <EOL> if self . app : <EOL> self . app . add_url_rule ( rule , view_func = view , endpoint = endpoint , methods = methods ) <EOL> else : <EOL> self . views . append ( ( route , resource , view , endpoint , methods ) ) <EOL> def add_resource ( self , resource ) : <EOL> """<STR_LIT>""" <EOL> if resource in self . resources . values ( ) : <EOL> return <EOL> if resource . api is not None and resource . api != self : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> if issubclass ( resource , ModelResource ) and resource . manager is None : <EOL> if self . default_manager : <EOL> resource . manager = self . default_manager ( resource , resource . meta . get ( '<STR_LIT>' ) ) <EOL> else : <EOL> raise RuntimeError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( resource . meta . name ) ) <EOL> resource . api = self <EOL> resource . route_prefix = '<STR_LIT>' . join ( ( self . prefix , '<STR_LIT:/>' , resource . meta . name ) ) <EOL> for route in resource . routes . values ( ) : <EOL> route_decorator = resource . meta . route_decorators . get ( route . relation , None ) <EOL> self . add_route ( route , resource , decorator = route_decorator ) <EOL> for name , rset in inspect . getmembers ( resource , lambda m : isinstance ( m , RouteSet ) ) : <EOL> if rset . attribute is None : <EOL> rset . attribute = name <EOL> for i , route in enumerate ( rset . routes ( ) ) : <EOL> if route . attribute is None : <EOL> route . attribute = '<STR_LIT>' . format ( rset . attribute , i ) <EOL> resource . routes [ '<STR_LIT>' . format ( rset . attribute , route . relation ) ] = route <EOL> self . add_route ( route , resource ) <EOL> self . resources [ resource . meta . name ] = resource </s>
