
    )`i8,                        d dl mZ d dlmZmZmZ d dlmZmZ d dl	m
Z
 ddlmZ ddlmZ d	ed
efdZ ed           G d d                      Z	 	 ddedeee                  deeegee         f                  d
dfdZ	 	 dd	edeeegee         f                  d
efdZ	 ddeded	ed
dfdZ	 ddeded	ed
ee         fdZdeded
dfdZg dZdS )    )	dataclass)CallableListOptional)	APIRouterFastAPI)APIRoute   )logger   )handler_registryprefixreturnc                 p    | sdS |                      d          } | r|                     d          sd|  } | S )a  Normalize a URL prefix to ensure consistent path handling.

    Args:
        prefix: The URL prefix to normalize

    Returns:
        Normalized prefix with leading slash and no trailing slash,
        or empty string if input is empty/None

    Examples:
        normalize_prefix("api/v1/") -> "/api/v1"
        normalize_prefix("/api/v1") -> "/api/v1"
        normalize_prefix("api/v1") -> "/api/v1"
        normalize_prefix("") -> ""
        normalize_prefix("/") -> ""
     /)rstrip
startswith)r   s    /home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/model_hosting_container_standards/common/fastapi/routing.pynormalize_prefixr      sS    "  r ]]3F  f'',, VM    T)frozenc                   h    e Zd ZU dZeed<   eed<   dZeee                  ed<   dZ	ee         ed<   dS )RouteConfiga  Configuration for a handler route.

    This immutable dataclass defines all the metadata needed to mount a handler
    as a FastAPI route. The frozen=True ensures that route configurations cannot
    be accidentally modified after creation.

    Attributes:
        path: The URL path for the route (e.g., "/adapters", "/health")
        method: The HTTP method (e.g., "POST", "GET", "DELETE")
        tags: Optional list of tags for documentation grouping
        summary: Optional short summary for documentation
    pathmethodNtagssummary)
__name__
__module____qualname____doc__str__annotations__r   r   r   r    r   r   r   r   )   s]           IIIKKK $D(49
$$$!GXc]!!!!!r   r   Nrouterhandler_namesroute_resolverc           	      p   |t          j        d           dS ||nt          j                    }t          j        dt          |           d           t          j        d|            |D ]}t          j        |          }|s	  ||          }|rW|                     |j	        ||j
        g|j        |j                   t          j        d|j
         d|j	         d	|            nt          j        d
| d           # t          $ r$}t          j        d
| d|            Y d}~d}~ww xY wdS )a  Mount handlers to a FastAPI router with their configured routes.

    This function iterates through registered handlers and mounts them to the provided
    router using route configurations obtained from the route_resolver function. This
    design allows different handler types to provide their own routing logic without
    modifying this generic mounting code.

    The mounting process:
    1. Determine which handlers to mount (all registered, or a specific subset)
    2. For each handler type, get the handler function from the registry
    3. Use the route_resolver to get the route configuration
    4. Mount the handler to the router if a configuration exists

    Args:
        router: FastAPI APIRouter instance to mount handlers to
        handler_names: Optional list of specific handler types to mount.
                      If None, attempts to mount all registered handlers.
                      Useful when you only want to expose certain handlers.
        route_resolver: Function that maps handler_name (str) -> RouteConfig.
                       This function encapsulates the routing logic for a specific
                       handler category (e.g., LoRA handlers, monitoring handlers).
                       If None, a warning is logged and no routes are mounted.

    Notes:
        - Handlers without route configurations are skipped (logged at DEBUG level)
        - ValueError exceptions from the route_resolver are caught and logged
        - Successfully mounted handlers are logged at INFO level
    NznNo route_resolver provided to mount_handlers. No routes will be mounted. This is likely a configuration error.z	Mounting z handlers to routerzHandlers to mount: )methodsr   r   zMounted handler:  z -> z	Skipping z - no default route configuredz - no route mapping available: )r   warningr   list_handlersinfolendebugget_handleradd_api_router   r   r   r   
ValueError)r&   r'   r(   handlers_to_mounthandler_namehandlerroute_configes           r   mount_handlersr9   >   s   D O	
 	
 	
 	 '28H8V8X8X  KGC 122GGGHHH
L:'8::;;; * W W".|<<  		W)>,77L W$$ %)01%*(0 %    )(; ) )l>O ) )&) )    UUUUVVV 	W 	W 	WLU\UURSUUVVVVVVVV	W;W Ws   A<D
D3D..D3r   c           	         t          j        d|  d|                    dg                       t          d	d| i|}t          j        d           t          ||           t          j        dt          |j                   d           |S )
a  Create a FastAPI router with handlers pre-mounted.

    This is a convenience function that combines router creation and handler mounting
    in a single step. It's useful when you want to create a self-contained router
    with all handlers already configured.

    Args:
        prefix: Optional URL prefix for all routes (e.g., "/api/v1", "/lora").
               All handler routes will be relative to this prefix.
        route_resolver: Function that maps handler_name (str) -> RouteConfig.
                       See mount_handlers() for details.
        **router_kwargs: Additional keyword arguments passed to APIRouter constructor.
                        Common options include:
                        - tags: List of tags for all routes
                        - dependencies: List of FastAPI dependencies

    Returns:
        APIRouter: A configured FastAPI router with handlers mounted
    zCreating router with prefix='z', tags=r   r   z1Router instance created, now mounting handlers...)r(   zRouter created with  routesr%   )r   r.   getr   r0   r9   r/   routes)r   r(   router_kwargsr&   s       r   create_routerr?      s    0 KWWW8I8I&RT8U8UWW  
 66f666F
LDEEE 6.9999
KBs6='9'9BBBCCCMr   appc                    t          |          }t                      }|j        D ]c}t          |t                    rL|r| |j         n|j        }t          t          |j                            }|	                    ||f           d|sdS | j
        j        }d}t          t          |          dz
  dd          D ]o}	||	         }t          |t                    rP|j        }
t          t          |j                            }|
|f|v r"t          j        d| d|
            ||	= |dz  }p|dk    r!d| _        t          j        d| d           dS dS )	zRemove conflicting routes from app before including router.

    Args:
        app: The FastAPI application
        router: The router to be included
        prefix: URL prefix that will be applied to router routes
    Nr      zRemoving conflicting route: r+   zRemoved z conflicting routes)r   setr=   
isinstancer	   r   tuplesortedr*   addr&   ranger/   r   r.   openapi_schema)r@   r&   r   incoming_routesrouterouter_pathrouter_methods
app_routesremoved_counti
route_pathroute_methodss               r   remove_conflicting_routesrT      s    f%%F eeO ? ?eX&& 	?5;KV1UZ111K"6%-#8#899Nn =>>>  "JM3z??Q&B// 	# 	#1eX&& 	#J!&"7"788MM*o==W=WW:WWXXXqM"q!A}AAABBBBB r   c           	         t          |          }t                      }| j        j        D ]R}t	          |t
                    r;|                    |j        t          t          |j
                            f           Sg }|j        D ]}t	          |t
                    rj|r| |j         n|j        }t          t          |j
                            }||f|v r/d                    |          }|                    | d|            |S )a=  Check for route conflicts between existing app routes and router routes.

    Args:
        app: The FastAPI application to check
        router: The router to be included
        prefix: URL prefix that will be applied to router routes

    Returns:
        List of conflict descriptions (empty if no conflicts)
    z, r+   )r   rD   r&   r=   rE   r	   rH   r   rF   rG   r*   joinappend)	r@   r&   r   existing_pathsrL   	conflictsrM   rN   methods_strs	            r   check_route_conflictsr[      s    f%%F UUN" K KeX&& 	K
E&2G2G,H,HIJJJ I A AeX&& 	A5;KV1UZ111K"6%-#8#899N^,>>"ii77  K!?!?+!?!?@@@r   c                    t          j        d           t          | |          }|r=d                    |          }t          j        d|            t          | |           nt          j        d           |                     |           t          d |j	        D                       }t          j        d| d           dS )	a  Safely include a router in a FastAPI app with automatic conflict resolution.

    This function automatically replaces any conflicting routes and warns about
    conflicts in the logs. This ensures predictable behavior where the most
    recently included router takes precedence.

    Args:
        app: The FastAPI application
        router: The router to include

    Example:
        # Simple inclusion with automatic conflict resolution
        safe_include_router(app, my_router)
    z(Including router with conflict detectionz
  - zNRoute conflicts detected. The following existing routes will be replaced:
  - zNo route conflicts detectedc                 <    g | ]}t          |t                    |S r%   )rE   r	   ).0rs     r   
<listcomp>z'safe_include_router.<locals>.<listcomp>.  s'    KKKQ:a3J3JKqKKKr   z"Successfully included router with r;   N)
r   r.   r[   rV   r,   rT   r0   include_routerr/   r=   )r@   r&   rY   conflict_listroute_counts        r   safe_include_routerrd     s    $ K:;;; &c622I 4 i00m^kmm	
 	
 	
 	"#v....2333 vKK&-KKKLLK
KI[IIIJJJJJr   )r   r   r9   r?   rT   r[   rd   )NN)r   N)r   )dataclassesr   typingr   r   r   fastapir   r   fastapi.routingr	   logging_configr   r6   r   r#   r   r   r9   r?   rT   r[   rd   __all__r%   r   r   <module>rk      s   ! ! ! ! ! ! + + + + + + + + + + & & & & & & & & $ $ $ $ $ $ $ $ $ $ $ $ & & & & & &S S    < $" " " " " " " ", *.GKQW QWQWDI&QW XseXk-B&BCDQW 
	QW QW QW QWj GK& &&XseXk-B&BCD& 	& & & &T 46)C )C	)C#)C-0)C	)C )C )C )CZ 46! !	!#!-0!	#Y! ! ! !H$K	$K$K 
$K $K $K $KN  r   