+
    }i                        ^ RI Ht ^ RIt^ RIHtHt ^ RIHtHt ^ RI	H
t
 ^ RIHt ^ RIHt R.t^ R	IHt ]! R
]R7      t]].]R,          3,          t]! R4       ! R R]],          4      4       tR# )    )annotationsN)	AwaitableCallable)GenericTypeVar)RequestState)BasicCrawlingContext)
docs_groupRouter)UserHandlerTimeoutErrorTCrawlingContext)boundOtherc                  J    ] tR t^tRtR R ltR R ltR R ltR R	 ltR
t	R# )r   a  A request dispatching system that routes requests to registered handlers based on their labels.

The `Router` allows you to define and register request handlers for specific labels. When a request is received,
the router invokes the corresponding `request_handler` based on the request's `label`. If no matching handler
is found, the default handler is used.

### Usage

```python
from crawlee.crawlers import HttpCrawler, HttpCrawlingContext
from crawlee.router import Router

router = Router[HttpCrawlingContext]()


# Handler for requests without a matching label handler
@router.default_handler
async def default_handler(context: HttpCrawlingContext) -> None:
    context.log.info(f'Request without label {context.request.url} ...')


# Handler for category requests
@router.handler(label='category')
async def category_handler(context: HttpCrawlingContext) -> None:
    context.log.info(f'Category request {context.request.url} ...')


# Handler for product requests
@router.handler(label='product')
async def product_handler(context: HttpCrawlingContext) -> None:
    context.log.info(f'Product {context.request.url} ...')


async def main() -> None:
    crawler = HttpCrawler(request_handler=router)
    await crawler.run()
c                   V ^8  d   QhRR/# )   returnNone )formats   "`/Users/ahmad/.openclaw/workspace/my-crawler/.venv/lib/python3.14/site-packages/crawlee/router.py__annotate__Router.__annotate__;   s     P P$ P    c                	l    R V n         \        \        \        \        ,          3,          ! 4       V n        R # N)_default_handlerdictstrRequestHandlerr   _handlers_by_label)selfs   &r   __init__Router.__init__;   s%    IM"&sN;K,L'L"M"Or   c               $    V ^8  d   QhRRRRRR/# )r   r"   r   handlerz RequestHandler[TCrawlingContext]r   r   )r   s   "r   r   r   ?   s#      f /O Tt r   c                D    V P                   e   \        R4      hWn         V# )zRegister a default request handler.

The default request handler is invoked for requests that have either no label or a label for which we have
no matching handler.
z'A default handler is already configured)r   RuntimeError)r"   r&   s   &&r   default_handlerRouter.default_handler?   s'       ,HII 'r   c                    V ^8  d   QhRRRR/# )r   labelr   r   zUCallable[[RequestHandler[TCrawlingContext]], Callable[[TCrawlingContext], Awaitable]]r   )r   s   "r   r   r   L   s       
_r   c                ^   a a SS P                   9   d   \        RS R24      hR VV 3R llpV# )zRegister a request handler based on a label.

This decorator registers a request handler for a specific label. The handler will be invoked only for requests
that have the exact same label.
zA handler for label `z` is already registeredc                    V ^8  d   QhRRRR/# )r   r&   z'Callable[[TCrawlingContext], Awaitable]r   r   )r   s   "r   r   $Router.handler.<locals>.__annotate__X   s     	 	D 	Ip 	r   c                &   < V SP                   S&   V # r   )r!   )r&   r,   r"   s   &r   wrapperRouter.handler.<locals>.wrapperX   s    -4D##E*Nr   )r!   r(   )r"   r,   r1   s   ff r   r&   Router.handlerL   s:     D+++!6ug=TUVV	 	 r   c                    V ^8  d   QhRRRR/# )r   contextr   r   r   r   )r   s   "r   r   r   ^   s     [ [&6 [4 [r   c                  "   \         P                  VP                  n        VP                  P                  e&   VP                  P                  V P
                  9  d?   V P                  f$   \        RVP                  P                   R24      hV P                  pM'V P
                  VP                  P                  ,          p V! V4      G Rj  xL
 #  L  \        P                   d   p\        R4      ThRp?ii ; i5i)zIInvoke a request handler that matches the request label (or the default).NzNo handler matches label `z&` and no default handler is configuredz&Timeout raised by user defined handler)r   REQUEST_HANDLERrequeststater,   r!   r   r(   asyncioTimeoutErrorr   )r"   r5   user_defined_handleres   &&  r   __call__Router.__call__^   s      , < <??  (GOO,A,AI`I`,`$$,"01F1F0GGmn  $(#8#8 #'#:#:7??;P;P#Q 	[-g6666## 	[)*RSYZZ	[s<   CD C CC D C C=,C88C==D )r   r!   N)
__name__
__module____qualname____firstlineno____doc__r#   r)   r&   r>   __static_attributes__r   r   r   r   r      s$    $LP$[ [r   )
__future__r   r:   collections.abcr   r   typingr   r   crawlee._requestr   crawlee._typesr	   crawlee._utils.docsr
   __all__crawlee.errorsr   r   r    r   r   r   r   <module>rN      sv    "  / # ) / ** 2-5IJ +,io=> G[[W%& [[ [[r   