<s> import functools <EOL> import inspect <EOL> import math <EOL> import time <EOL> from oslo_log import log as logging <EOL> from oslo_serialization import jsonutils <EOL> from oslo_utils import strutils <EOL> import six <EOL> import webob <EOL> from nova . api . openstack import api_version_request as api_version <EOL> from nova . api . openstack import versioned_method <EOL> from nova import exception <EOL> from nova import i18n <EOL> from nova . i18n import _ <EOL> from nova . i18n import _LE <EOL> from nova . i18n import _LI <EOL> from nova import utils <EOL> from nova import wsgi <EOL> LOG = logging . getLogger ( __name__ ) <EOL> _SUPPORTED_CONTENT_TYPES = ( <EOL> '<STR_LIT:application/json>' , <EOL> '<STR_LIT>' , <EOL> ) <EOL> _MEDIA_TYPE_MAP = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:application/json>' : '<STR_LIT>' , <EOL> } <EOL> _ROUTES_METHODS = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> _METHODS_WITH_BODY = [ <EOL> '<STR_LIT:POST>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> DEFAULT_API_VERSION = "<STR_LIT>" <EOL> VER_METHOD_ATTR = '<STR_LIT>' <EOL> API_VERSION_REQUEST_HEADER = '<STR_LIT>' <EOL> ENV_LEGACY_V2 = '<STR_LIT>' <EOL> def get_supported_content_types ( ) : <EOL> return _SUPPORTED_CONTENT_TYPES <EOL> def get_media_map ( ) : <EOL> return dict ( _MEDIA_TYPE_MAP . items ( ) ) <EOL> def item_get ( item , item_key ) : <EOL> if hasattr ( item , '<STR_LIT>' ) : <EOL> return item [ item_key ] <EOL> else : <EOL> return getattr ( item , item_key ) <EOL> class Request ( wsgi . Request ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( Request , self ) . __init__ ( * args , ** kwargs ) <EOL> self . _extension_data = { '<STR_LIT>' : { } } <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . api_version_request = api_version . APIVersionRequest ( ) <EOL> def cache_db_items ( self , key , items , item_key = '<STR_LIT:id>' ) : <EOL> """<STR_LIT>""" <EOL> db_items = self . _extension_data [ '<STR_LIT>' ] . setdefault ( key , { } ) <EOL> for item in items : <EOL> db_items [ item_get ( item , item_key ) ] = item <EOL> def get_db_items ( self , key ) : <EOL> """<STR_LIT>""" <EOL> return self . _extension_data [ '<STR_LIT>' ] [ key ] <EOL> def get_db_item ( self , key , item_key ) : <EOL> """<STR_LIT>""" <EOL> return self . get_db_items ( key ) . get ( item_key ) <EOL> def cache_db_instances ( self , instances ) : <EOL> self . cache_db_items ( '<STR_LIT>' , instances , '<STR_LIT>' ) <EOL> def cache_db_instance ( self , instance ) : <EOL> self . cache_db_items ( '<STR_LIT>' , [ instance ] , '<STR_LIT>' ) <EOL> def get_db_instances ( self ) : <EOL> return self . get_db_items ( '<STR_LIT>' ) <EOL> def get_db_instance ( self , instance_uuid ) : <EOL> return self . get_db_item ( '<STR_LIT>' , instance_uuid ) <EOL> def cache_db_flavors ( self , flavors ) : <EOL> self . cache_db_items ( '<STR_LIT>' , flavors , '<STR_LIT>' ) <EOL> def cache_db_flavor ( self , flavor ) : <EOL> self . cache_db_items ( '<STR_LIT>' , [ flavor ] , '<STR_LIT>' ) <EOL> def get_db_flavors ( self ) : <EOL> return self . get_db_items ( '<STR_LIT>' ) <EOL> def get_db_flavor ( self , flavorid ) : <EOL> return self . get_db_item ( '<STR_LIT>' , flavorid ) <EOL> def cache_db_compute_nodes ( self , compute_nodes ) : <EOL> self . cache_db_items ( '<STR_LIT>' , compute_nodes , '<STR_LIT:id>' ) <EOL> def cache_db_compute_node ( self , compute_node ) : <EOL> self . cache_db_items ( '<STR_LIT>' , [ compute_node ] , '<STR_LIT:id>' ) <EOL> def get_db_compute_nodes ( self ) : <EOL> return self . get_db_items ( '<STR_LIT>' ) <EOL> def get_db_compute_node ( self , id ) : <EOL> return self . get_db_item ( '<STR_LIT>' , id ) <EOL> def best_match_content_type ( self ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' not in self . environ : <EOL> content_type = None <EOL> parts = self . path . rsplit ( '<STR_LIT:.>' , <NUM_LIT:1> ) <EOL> if len ( parts ) > <NUM_LIT:1> : <EOL> possible_type = '<STR_LIT>' + parts [ <NUM_LIT:1> ] <EOL> if possible_type in get_supported_content_types ( ) : <EOL> content_type = possible_type <EOL> if not content_type : <EOL> content_type = self . accept . best_match ( <EOL> get_supported_content_types ( ) ) <EOL> self . environ [ '<STR_LIT>' ] = ( content_type or <EOL> '<STR_LIT:application/json>' ) <EOL> return self . environ [ '<STR_LIT>' ] <EOL> def get_content_type ( self ) : <EOL> """<STR_LIT>""" <EOL> if "<STR_LIT:Content-Type>" not in self . headers : <EOL> return None <EOL> content_type = self . content_type <EOL> if not content_type or content_type == '<STR_LIT>' : <EOL> return None <EOL> if content_type not in get_supported_content_types ( ) : <EOL> raise exception . InvalidContentType ( content_type = content_type ) <EOL> return content_type <EOL> def best_match_language ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . accept_language : <EOL> return None <EOL> return self . accept_language . best_match ( <EOL> i18n . get_available_languages ( ) ) <EOL> def set_api_version_request ( self ) : <EOL> """<STR_LIT>""" <EOL> if API_VERSION_REQUEST_HEADER in self . headers : <EOL> hdr_string = self . headers [ API_VERSION_REQUEST_HEADER ] <EOL> if hdr_string == '<STR_LIT>' : <EOL> self . api_version_request = api_version . max_api_version ( ) <EOL> else : <EOL> self . api_version_request = api_version . APIVersionRequest ( <EOL> hdr_string ) <EOL> if not self . api_version_request . matches ( <EOL> api_version . min_api_version ( ) , <EOL> api_version . max_api_version ( ) ) : <EOL> raise exception . InvalidGlobalAPIVersion ( <EOL> req_ver = self . api_version_request . get_string ( ) , <EOL> min_ver = api_version . min_api_version ( ) . get_string ( ) , <EOL> max_ver = api_version . max_api_version ( ) . get_string ( ) ) <EOL> else : <EOL> self . api_version_request = api_version . APIVersionRequest ( <EOL> api_version . DEFAULT_API_VERSION ) <EOL> def set_legacy_v2 ( self ) : <EOL> self . environ [ ENV_LEGACY_V2 ] = True <EOL> def is_legacy_v2 ( self ) : <EOL> return self . environ . get ( ENV_LEGACY_V2 , False ) <EOL> class ActionDispatcher ( object ) : <EOL> """<STR_LIT>""" <EOL> def dispatch ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> action = kwargs . pop ( '<STR_LIT:action>' , '<STR_LIT:default>' ) <EOL> action_method = getattr ( self , str ( action ) , self . default ) <EOL> return action_method ( * args , ** kwargs ) <EOL> def default ( self , data ) : <EOL> raise NotImplementedError ( ) <EOL> class JSONDeserializer ( ActionDispatcher ) : <EOL> def _from_json ( self , datastring ) : <EOL> try : <EOL> return jsonutils . loads ( datastring ) <EOL> except ValueError : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> raise exception . MalformedRequestBody ( reason = msg ) <EOL> def deserialize ( self , datastring , action = '<STR_LIT:default>' ) : <EOL> return self . dispatch ( datastring , action = action ) <EOL> def default ( self , datastring ) : <EOL> return { '<STR_LIT:body>' : self . _from_json ( datastring ) } <EOL> class JSONDictSerializer ( ActionDispatcher ) : <EOL> """<STR_LIT>""" <EOL> def serialize ( self , data , action = '<STR_LIT:default>' ) : <EOL> return self . dispatch ( data , action = action ) <EOL> def default ( self , data ) : <EOL> return six . text_type ( jsonutils . dumps ( data ) ) <EOL> def response ( code ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> func . wsgi_code = code <EOL> return func <EOL> return decorator <EOL> class ResponseObject ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , obj , code = None , headers = None ) : <EOL> """<STR_LIT>""" <EOL> self . obj = obj <EOL> self . _default_code = <NUM_LIT:200> <EOL> self . _code = code <EOL> self . _headers = headers or { } <EOL> self . serializer = JSONDictSerializer ( ) <EOL> def __getitem__ ( self , key ) : <EOL> """<STR_LIT>""" <EOL> return self . _headers [ key . lower ( ) ] <EOL> def __setitem__ ( self , key , value ) : <EOL> """<STR_LIT>""" <EOL> self . _headers [ key . lower ( ) ] = value <EOL> def __delitem__ ( self , key ) : <EOL> """<STR_LIT>""" <EOL> del self . _headers [ key . lower ( ) ] <EOL> def serialize ( self , request , content_type ) : <EOL> """<STR_LIT>""" <EOL> serializer = self . serializer <EOL> body = None <EOL> if self . obj is not None : <EOL> body = serializer . serialize ( self . obj ) <EOL> response = webob . Response ( body = body ) <EOL> if response . headers . get ( '<STR_LIT>' ) : <EOL> response . headers [ '<STR_LIT>' ] = utils . utf8 ( <EOL> response . headers [ '<STR_LIT>' ] ) <EOL> response . status_int = self . code <EOL> for hdr , value in self . _headers . items ( ) : <EOL> response . headers [ hdr ] = utils . utf8 ( value ) <EOL> response . headers [ '<STR_LIT:Content-Type>' ] = utils . utf8 ( content_type ) <EOL> return response <EOL> @ property <EOL> def code ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _code or self . _default_code <EOL> @ property <EOL> def headers ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _headers . copy ( ) <EOL> def action_peek ( body ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> decoded = jsonutils . loads ( body ) <EOL> except ValueError : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> raise exception . MalformedRequestBody ( reason = msg ) <EOL> if len ( decoded ) != <NUM_LIT:1> : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> raise exception . MalformedRequestBody ( reason = msg ) <EOL> return list ( decoded . keys ( ) ) [ <NUM_LIT:0> ] <EOL> class ResourceExceptionHandler ( object ) : <EOL> """<STR_LIT>""" <EOL> def __enter__ ( self ) : <EOL> return None <EOL> def __exit__ ( self , ex_type , ex_value , ex_traceback ) : <EOL> if not ex_value : <EOL> return True <EOL> if isinstance ( ex_value , exception . Forbidden ) : <EOL> raise Fault ( webob . exc . HTTPForbidden ( <EOL> explanation = ex_value . format_message ( ) ) ) <EOL> elif isinstance ( ex_value , exception . VersionNotFoundForAPIMethod ) : <EOL> raise <EOL> elif isinstance ( ex_value , exception . Invalid ) : <EOL> raise Fault ( exception . ConvertedException ( <EOL> code = ex_value . code , <EOL> explanation = ex_value . format_message ( ) ) ) <EOL> elif isinstance ( ex_value , TypeError ) : <EOL> exc_info = ( ex_type , ex_value , ex_traceback ) <EOL> LOG . error ( _LE ( '<STR_LIT>' ) , ex_value , <EOL> exc_info = exc_info ) <EOL> raise Fault ( webob . exc . HTTPBadRequest ( ) ) <EOL> elif isinstance ( ex_value , Fault ) : <EOL> LOG . info ( _LI ( "<STR_LIT>" ) , ex_value ) <EOL> raise ex_value <EOL> elif isinstance ( ex_value , webob . exc . HTTPException ) : <EOL> LOG . info ( _LI ( "<STR_LIT>" ) , ex_value ) <EOL> raise Fault ( ex_value ) <EOL> return False <EOL> class Resource ( wsgi . Application ) : <EOL> """<STR_LIT>""" <EOL> support_api_request_version = False <EOL> def __init__ ( self , controller , inherits = None ) : <EOL> """<STR_LIT>""" <EOL> self . controller = controller <EOL> self . default_serializers = dict ( json = JSONDictSerializer ) <EOL> self . wsgi_actions = { } <EOL> if controller : <EOL> self . register_actions ( controller ) <EOL> self . wsgi_extensions = { } <EOL> self . wsgi_action_extensions = { } <EOL> self . inherits = inherits <EOL> def register_actions ( self , controller ) : <EOL> """<STR_LIT>""" <EOL> actions = getattr ( controller , '<STR_LIT>' , { } ) <EOL> for key , method_name in actions . items ( ) : <EOL> self . wsgi_actions [ key ] = getattr ( controller , method_name ) <EOL> def register_extensions ( self , controller ) : <EOL> """<STR_LIT>""" <EOL> extensions = getattr ( controller , '<STR_LIT>' , [ ] ) <EOL> for method_name , action_name in extensions : <EOL> extension = getattr ( controller , method_name ) <EOL> if action_name : <EOL> if action_name not in self . wsgi_action_extensions : <EOL> self . wsgi_action_extensions [ action_name ] = [ ] <EOL> self . wsgi_action_extensions [ action_name ] . append ( extension ) <EOL> else : <EOL> if method_name not in self . wsgi_extensions : <EOL> self . wsgi_extensions [ method_name ] = [ ] <EOL> self . wsgi_extensions [ method_name ] . append ( extension ) <EOL> def get_action_args ( self , request_environment ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self . controller , '<STR_LIT>' ) : <EOL> return self . controller . get_action_args ( request_environment ) <EOL> try : <EOL> args = request_environment [ '<STR_LIT>' ] [ <NUM_LIT:1> ] . copy ( ) <EOL> except ( KeyError , IndexError , AttributeError ) : <EOL> return { } <EOL> try : <EOL> del args [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> pass <EOL> try : <EOL> del args [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> pass <EOL> return args <EOL> def get_body ( self , request ) : <EOL> content_type = request . get_content_type ( ) <EOL> return content_type , request . body <EOL> def deserialize ( self , body ) : <EOL> return JSONDeserializer ( ) . deserialize ( body ) <EOL> def pre_process_extensions ( self , extensions , request , action_args ) : <EOL> post = [ ] <EOL> for ext in extensions : <EOL> if inspect . isgeneratorfunction ( ext ) : <EOL> response = None <EOL> try : <EOL> with ResourceExceptionHandler ( ) : <EOL> gen = ext ( req = request , ** action_args ) <EOL> response = next ( gen ) <EOL> except Fault as ex : <EOL> response = ex <EOL> if response : <EOL> return response , [ ] <EOL> post . append ( gen ) <EOL> else : <EOL> post . append ( ext ) <EOL> return None , reversed ( post ) <EOL> def post_process_extensions ( self , extensions , resp_obj , request , <EOL> action_args ) : <EOL> for ext in extensions : <EOL> response = None <EOL> if inspect . isgenerator ( ext ) : <EOL> try : <EOL> with ResourceExceptionHandler ( ) : <EOL> response = ext . send ( resp_obj ) <EOL> except StopIteration : <EOL> continue <EOL> except Fault as ex : <EOL> response = ex <EOL> else : <EOL> try : <EOL> with ResourceExceptionHandler ( ) : <EOL> response = ext ( req = request , resp_obj = resp_obj , <EOL> ** action_args ) <EOL> except exception . VersionNotFoundForAPIMethod : <EOL> continue <EOL> except Fault as ex : <EOL> response = ex <EOL> if response : <EOL> return response <EOL> return None <EOL> def _should_have_body ( self , request ) : <EOL> return request . method in _METHODS_WITH_BODY <EOL> @ webob . dec . wsgify ( RequestClass = Request ) <EOL> def __call__ ( self , request ) : <EOL> """<STR_LIT>""" <EOL> if self . support_api_request_version : <EOL> try : <EOL> request . set_api_version_request ( ) <EOL> except exception . InvalidAPIVersionString as e : <EOL> return Fault ( webob . exc . HTTPBadRequest ( <EOL> explanation = e . format_message ( ) ) ) <EOL> except exception . InvalidGlobalAPIVersion as e : <EOL> return Fault ( webob . exc . HTTPNotAcceptable ( <EOL> explanation = e . format_message ( ) ) ) <EOL> action_args = self . get_action_args ( request . environ ) <EOL> action = action_args . pop ( '<STR_LIT:action>' , None ) <EOL> try : <EOL> content_type , body = self . get_body ( request ) <EOL> accept = request . best_match_content_type ( ) <EOL> except exception . InvalidContentType : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> return Fault ( webob . exc . HTTPBadRequest ( explanation = msg ) ) <EOL> return self . _process_stack ( request , action , action_args , <EOL> content_type , body , accept ) <EOL> def _process_stack ( self , request , action , action_args , <EOL> content_type , body , accept ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> meth , extensions = self . get_method ( request , action , <EOL> content_type , body ) <EOL> except ( AttributeError , TypeError ) : <EOL> return Fault ( webob . exc . HTTPNotFound ( ) ) <EOL> except KeyError as ex : <EOL> msg = _ ( "<STR_LIT>" ) % ex . args [ <NUM_LIT:0> ] <EOL> return Fault ( webob . exc . HTTPBadRequest ( explanation = msg ) ) <EOL> except exception . MalformedRequestBody : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> return Fault ( webob . exc . HTTPBadRequest ( explanation = msg ) ) <EOL> if body : <EOL> msg = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) % { '<STR_LIT:action>' : action , <EOL> '<STR_LIT:body>' : six . text_type ( body , '<STR_LIT:utf-8>' ) , <EOL> '<STR_LIT>' : str ( meth ) } <EOL> LOG . debug ( strutils . mask_password ( msg ) ) <EOL> else : <EOL> LOG . debug ( "<STR_LIT>" , <EOL> { '<STR_LIT>' : str ( meth ) } ) <EOL> try : <EOL> contents = { } <EOL> if self . _should_have_body ( request ) : <EOL> if request . content_length == <NUM_LIT:0> : <EOL> contents = { '<STR_LIT:body>' : None } <EOL> else : <EOL> contents = self . deserialize ( body ) <EOL> except exception . MalformedRequestBody : <EOL> msg = _ ( "<STR_LIT>" ) <EOL> return Fault ( webob . exc . HTTPBadRequest ( explanation = msg ) ) <EOL> action_args . update ( contents ) <EOL> project_id = action_args . pop ( "<STR_LIT>" , None ) <EOL> context = request . environ . get ( '<STR_LIT>' ) <EOL> if ( context and project_id and ( project_id != context . project_id ) ) : <EOL> msg = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % { '<STR_LIT>' : project_id , <EOL> '<STR_LIT>' : context . project_id } <EOL> return Fault ( webob . exc . HTTPBadRequest ( explanation = msg ) ) <EOL> response , post = self . pre_process_extensions ( extensions , <EOL> request , action_args ) <EOL> if not response : <EOL> try : <EOL> with ResourceExceptionHandler ( ) : <EOL> action_result = self . dispatch ( meth , request , action_args ) <EOL> except Fault as ex : <EOL> response = ex <EOL> if not response : <EOL> resp_obj = None <EOL> if type ( action_result ) is dict or action_result is None : <EOL> resp_obj = ResponseObject ( action_result ) <EOL> elif isinstance ( action_result , ResponseObject ) : <EOL> resp_obj = action_result <EOL> else : <EOL> response = action_result <EOL> if resp_obj : <EOL> if hasattr ( meth , '<STR_LIT>' ) : <EOL> resp_obj . _default_code = meth . wsgi_code <EOL> response = self . post_process_extensions ( post , resp_obj , <EOL> request , action_args ) <EOL> if resp_obj and not response : <EOL> response = resp_obj . serialize ( request , accept ) <EOL> if hasattr ( response , '<STR_LIT>' ) : <EOL> for hdr , val in list ( response . headers . items ( ) ) : <EOL> response . headers [ hdr ] = utils . utf8 ( val ) <EOL> if not request . api_version_request . is_null ( ) : <EOL> response . headers [ API_VERSION_REQUEST_HEADER ] = request . api_version_request . get_string ( ) <EOL> response . headers [ '<STR_LIT>' ] = API_VERSION_REQUEST_HEADER <EOL> return response <EOL> def get_method ( self , request , action , content_type , body ) : <EOL> meth , extensions = self . _get_method ( request , <EOL> action , <EOL> content_type , <EOL> body ) <EOL> if self . inherits : <EOL> _meth , parent_ext = self . inherits . get_method ( request , <EOL> action , <EOL> content_type , <EOL> body ) <EOL> extensions . extend ( parent_ext ) <EOL> return meth , extensions <EOL> def _get_method ( self , request , action , content_type , body ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if not self . controller : <EOL> meth = getattr ( self , action ) <EOL> else : <EOL> meth = getattr ( self . controller , action ) <EOL> except AttributeError : <EOL> if ( not self . wsgi_actions or <EOL> action not in _ROUTES_METHODS + [ '<STR_LIT:action>' ] ) : <EOL> raise <EOL> else : <EOL> return meth , self . wsgi_extensions . get ( action , [ ] ) <EOL> if action == '<STR_LIT:action>' : <EOL> action_name = action_peek ( body ) <EOL> else : <EOL> action_name = action <EOL> return ( self . wsgi_actions [ action_name ] , <EOL> self . wsgi_action_extensions . get ( action_name , [ ] ) ) <EOL> def dispatch ( self , method , request , action_args ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return method ( req = request , ** action_args ) <EOL> except exception . VersionNotFoundForAPIMethod : <EOL> return Fault ( webob . exc . HTTPNotFound ( ) ) <EOL> class ResourceV21 ( Resource ) : <EOL> support_api_request_version = True <EOL> def action ( name ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> func . wsgi_action = name <EOL> return func <EOL> return decorator <EOL> def extends ( * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> func . wsgi_extends = ( func . __name__ , kwargs . get ( '<STR_LIT:action>' ) ) <EOL> return func <EOL> if args : <EOL> return decorator ( * args ) <EOL> return decorator <EOL> class ControllerMetaclass ( type ) : <EOL> """<STR_LIT>""" <EOL> def __new__ ( mcs , name , bases , cls_dict ) : <EOL> """<STR_LIT>""" <EOL> actions = { } <EOL> extensions = [ ] <EOL> versioned_methods = None <EOL> for base in bases : <EOL> actions . update ( getattr ( base , '<STR_LIT>' , { } ) ) <EOL> if base . __name__ == "<STR_LIT>" : <EOL> if VER_METHOD_ATTR in base . __dict__ : <EOL> versioned_methods = getattr ( base , VER_METHOD_ATTR ) <EOL> delattr ( base , VER_METHOD_ATTR ) <EOL> for key , value in cls_dict . items ( ) : <EOL> if not callable ( value ) : <EOL> continue <EOL> if getattr ( value , '<STR_LIT>' , None ) : <EOL> actions [ value . wsgi_action ] = key <EOL> elif getattr ( value , '<STR_LIT>' , None ) : <EOL> extensions . append ( value . wsgi_extends ) <EOL> cls_dict [ '<STR_LIT>' ] = actions <EOL> cls_dict [ '<STR_LIT>' ] = extensions <EOL> if versioned_methods : <EOL> cls_dict [ VER_METHOD_ATTR ] = versioned_methods <EOL> return super ( ControllerMetaclass , mcs ) . __new__ ( mcs , name , bases , <EOL> cls_dict ) <EOL> @ six . add_metaclass ( ControllerMetaclass ) <EOL> class Controller ( object ) : <EOL> """<STR_LIT>""" <EOL> _view_builder_class = None <EOL> def __init__ ( self , view_builder = None ) : <EOL> """<STR_LIT>""" <EOL> if view_builder : <EOL> self . _view_builder = view_builder <EOL> elif self . _view_builder_class : <EOL> self . _view_builder = self . _view_builder_class ( ) <EOL> else : <EOL> self . _view_builder = None <EOL> def __getattribute__ ( self , key ) : <EOL> def version_select ( * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if len ( args ) == <NUM_LIT:0> : <EOL> ver = kwargs [ '<STR_LIT>' ] . api_version_request <EOL> else : <EOL> ver = args [ <NUM_LIT:0> ] . api_version_request <EOL> func_list = self . versioned_methods [ key ] <EOL> for func in func_list : <EOL> if ver . matches ( func . start_version , func . end_version ) : <EOL> functools . update_wrapper ( version_select , func . func ) <EOL> return func . func ( self , * args , ** kwargs ) <EOL> raise exception . VersionNotFoundForAPIMethod ( version = ver ) <EOL> try : <EOL> version_meth_dict = object . __getattribute__ ( self , VER_METHOD_ATTR ) <EOL> except AttributeError : <EOL> return object . __getattribute__ ( self , key ) <EOL> if version_meth_dict and key in object . __getattribute__ ( self , VER_METHOD_ATTR ) : <EOL> return version_select <EOL> return object . __getattribute__ ( self , key ) <EOL> @ classmethod <EOL> def api_version ( cls , min_ver , max_ver = None ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( f ) : <EOL> obj_min_ver = api_version . APIVersionRequest ( min_ver ) <EOL> if max_ver : <EOL> obj_max_ver = api_version . APIVersionRequest ( max_ver ) <EOL> else : <EOL> obj_max_ver = api_version . APIVersionRequest ( ) <EOL> func_name = f . __name__ <EOL> new_func = versioned_method . VersionedMethod ( <EOL> func_name , obj_min_ver , obj_max_ver , f ) <EOL> func_dict = getattr ( cls , VER_METHOD_ATTR , { } ) <EOL> if not func_dict : <EOL> setattr ( cls , VER_METHOD_ATTR , func_dict ) <EOL> func_list = func_dict . get ( func_name , [ ] ) <EOL> if not func_list : <EOL> func_dict [ func_name ] = func_list <EOL> func_list . append ( new_func ) <EOL> func_list . sort ( key = lambda f : f . start_version , reverse = True ) <EOL> return f <EOL> return decorator <EOL> @ staticmethod <EOL> def is_valid_body ( body , entity_name ) : <EOL> if not ( body and entity_name in body ) : <EOL> return False <EOL> def is_dict ( d ) : <EOL> try : <EOL> d . get ( None ) <EOL> return True <EOL> except AttributeError : <EOL> return False <EOL> return is_dict ( body [ entity_name ] ) <EOL> class Fault ( webob . exc . HTTPException ) : <EOL> """<STR_LIT>""" <EOL> _fault_names = { <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" , <EOL> <NUM_LIT> : "<STR_LIT>" } <EOL> def __init__ ( self , exception ) : <EOL> """<STR_LIT>""" <EOL> self . wrapped_exc = exception <EOL> for key , value in list ( self . wrapped_exc . headers . items ( ) ) : <EOL> self . wrapped_exc . headers [ key ] = str ( value ) <EOL> self . status_int = exception . status_int <EOL> @ webob . dec . wsgify ( RequestClass = Request ) <EOL> def __call__ ( self , req ) : <EOL> """<STR_LIT>""" <EOL> user_locale = req . best_match_language ( ) <EOL> code = self . wrapped_exc . status_int <EOL> fault_name = self . _fault_names . get ( code , "<STR_LIT>" ) <EOL> explanation = self . wrapped_exc . explanation <EOL> LOG . debug ( "<STR_LIT>" , <EOL> { '<STR_LIT:code>' : code , '<STR_LIT>' : explanation } ) <EOL> explanation = i18n . translate ( explanation , user_locale ) <EOL> fault_data = { <EOL> fault_name : { <EOL> '<STR_LIT:code>' : code , <EOL> '<STR_LIT:message>' : explanation } } <EOL> if code == <NUM_LIT> or code == <NUM_LIT> : <EOL> retry = self . wrapped_exc . headers . get ( '<STR_LIT>' , None ) <EOL> if retry : <EOL> fault_data [ fault_name ] [ '<STR_LIT>' ] = retry <EOL> if not req . api_version_request . is_null ( ) : <EOL> self . wrapped_exc . headers [ API_VERSION_REQUEST_HEADER ] = req . api_version_request . get_string ( ) <EOL> self . wrapped_exc . headers [ '<STR_LIT>' ] = API_VERSION_REQUEST_HEADER <EOL> self . wrapped_exc . content_type = '<STR_LIT:application/json>' <EOL> self . wrapped_exc . charset = '<STR_LIT>' <EOL> self . wrapped_exc . text = JSONDictSerializer ( ) . serialize ( fault_data ) <EOL> return self . wrapped_exc <EOL> def __str__ ( self ) : <EOL> return self . wrapped_exc . __str__ ( ) <EOL> class RateLimitFault ( webob . exc . HTTPException ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , message , details , retry_time ) : <EOL> """<STR_LIT>""" <EOL> hdrs = RateLimitFault . _retry_after ( retry_time ) <EOL> self . wrapped_exc = webob . exc . HTTPTooManyRequests ( headers = hdrs ) <EOL> self . content = { <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT:code>" : self . wrapped_exc . status_int , <EOL> "<STR_LIT:message>" : message , <EOL> "<STR_LIT>" : details , <EOL> "<STR_LIT>" : hdrs [ '<STR_LIT>' ] , <EOL> } , <EOL> } <EOL> @ staticmethod <EOL> def _retry_after ( retry_time ) : <EOL> delay = int ( math . ceil ( retry_time - time . time ( ) ) ) <EOL> retry_after = delay if delay > <NUM_LIT:0> else <NUM_LIT:0> <EOL> headers = { '<STR_LIT>' : '<STR_LIT>' % retry_after } <EOL> return headers <EOL> @ webob . dec . wsgify ( RequestClass = Request ) <EOL> def __call__ ( self , request ) : <EOL> """<STR_LIT>""" <EOL> user_locale = request . best_match_language ( ) <EOL> self . content [ '<STR_LIT>' ] [ '<STR_LIT:message>' ] = i18n . translate ( self . content [ '<STR_LIT>' ] [ '<STR_LIT:message>' ] , user_locale ) <EOL> self . content [ '<STR_LIT>' ] [ '<STR_LIT>' ] = i18n . translate ( self . content [ '<STR_LIT>' ] [ '<STR_LIT>' ] , user_locale ) <EOL> content = JSONDictSerializer ( ) . serialize ( self . content ) <EOL> self . wrapped_exc . charset = '<STR_LIT>' <EOL> self . wrapped_exc . content_type = "<STR_LIT:application/json>" <EOL> self . wrapped_exc . text = content <EOL> return self . wrapped_exc </s>
