U
    cc                     @   sz   d dl Z d dlmZmZ ddlmZ e jrVd dl mZmZ ddl	m
Z
 edZedZG d	d
 d
eZG dd deZdS )    N)ABCMetaabstractmethod   )DispatchException)UnionTypeVar)RuntimeConfigurationInputOutputc                   @   s    e Zd ZdZeZedd ZdS )AbstractRequestDispatchera  Dispatcher which handles dispatching input request to the
    corresponding handler.

    User needs to implement the dispatch method, to handle the
    processing of the incoming request in the handler input. A response
    may be expected out of the dispatch method.
    c                 C   s   dS )a6  Dispatches an incoming request to the appropriate request
        handler and returns the output.

        :param handler_input: generic input to the dispatcher
        :type handler_input: Input
        :return: generic output returned by handler in the dispatcher
        :rtype: Union[None, Output]
        N )selfhandler_inputr   r   </tmp/pip-unpacked-wheel-yhqslwpj/ask_sdk_runtime/dispatch.pydispatch(   s    z"AbstractRequestDispatcher.dispatchN)__name__
__module____qualname____doc__r   __metaclass__r   r   r   r   r   r   r      s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	GenericRequestDispatchera  Generic implementation of :py:class:`AbstractRequestDispatcher`.

    The runtime configuration contains the components required for the
    dispatcher, which is passed during initialization.

    When the dispatch method is invoked, using a list of
    :py:class:`ask_sdk_runtime.dispatch_components.request_components.RequestMapper`
    , the Dispatcher finds a handler for the request and delegates the
    invocation to the supported
    :py:class:`ask_sdk_runtime.dispatch_components.request_components.HandlerAdapter`
    . If the handler raises any exception, it is delegated to
    :py:class:`ask_sdk_runtime.dispatch_components.exception_components.ExceptionMapper`
    to handle or raise it to the upper stack.
    c                 C   sl   |j dkrg |_ |jdkr g |_|jdkr0g |_|jdkr@g |_|j | _ |j| _|j| _|j| _|j| _dS )a  Generic implementation of :py:class:`RequestDispatcher`.

        :param options: Runtime configuration instance, containing list of
            dispatch components required for Dispatcher Initialization.
        :type options: RuntimeConfiguration
        N)handler_adaptersrequest_mappersrequest_interceptorsresponse_interceptorsexception_mapper)r   optionsr   r   r   __init__F   s    



z!GenericRequestDispatcher.__init__c              
   C   s   zB| j D ]}|j|d q| |}| jD ]}|j||d q*|W S  tk
r } z@| jdk	r| j||}|dkrx|||| W Y 
S |W 5 d}~X Y nX dS )a  Dispatches an incoming request to the appropriate
        request handler and returns the output.

        Before running the request on the appropriate request handler,
        dispatcher runs any predefined global request interceptors.
        On successful response returned from request handler, dispatcher
        runs predefined global response interceptors, before returning
        the response.

        :param handler_input: generic input to the dispatcher
        :type handler_input: Input
        :return: generic output handled by the handler, optionally
            containing a response
        :rtype: Union[None, Output]
        :raises: :py:class:`ask_sdk_runtime.exceptions.DispatchException`
        r   r   responseN)r   process+_GenericRequestDispatcher__dispatch_requestr   	Exceptionr   Zget_handlerhandle)r   r   Zrequest_interceptoroutputresponse_interceptoreZexception_handlerr   r   r   r   `   s(    


 
 z!GenericRequestDispatcher.dispatchc                 C   s   d}| j D ]}||}|dk	r
 q&q
|dkr6td|j}d}| jD ]}||rF|} q^qF|dkrntd|j}|D ]}|j|d qx|j||d}	|j	}
|
D ]}|j||	d q|	S )a  Process the request and return handler output.

        When the method is invoked, using the registered list of
        :py:class:`RequestMapper`, a Handler Chain is found that can
        handle the request. The handler invocation is delegated to the
        supported :py:class:`HandlerAdapter`. The registered
        request interceptors in the handler chain are processed before
        executing the handler. The registered response interceptors in
        the handler chain are processed after executing the handler.

        :param handler_input: generic input to the dispatcher containing
            incoming request and other context.
        :type handler_input: Input
        :return: Output from the 'handle' method execution of the
            supporting handler.
        :rtype: Union[None, Output]
        :raises DispatchException if there is no supporting
            handler chain or adapter
        Nz)Unable to find a suitable request handlerz)Unable to find a suitable request adapterr   )r   handlerr   )
r   Zget_request_handler_chainr   request_handlerr   Zsupportsr   r!   executer   )r   r   Zrequest_handler_chainZmapperr)   Zsupported_handler_adapteradapterZlocal_request_interceptorsZinterceptorr%   Zlocal_response_interceptorsr&   r   r   r   Z__dispatch_request   sH    


  z+GenericRequestDispatcher.__dispatch_requestN)r   r   r   r   r   r   r"   r   r   r   r   r   6   s   'r   )typingabcr   r   
exceptionsr   TYPE_CHECKINGr   r   Zskillr   r	   r
   objectr   r   r   r   r   r   <module>   s   