
    9i4=                        % S r SSKrSSKrSSKrSSKJr  SSKJrJrJ	r	J
r
  SSKJrJrJr  \(       a
  SSKrSSKJr  \" 5       (       a  SSKJrJr  SS	KJr  OS=r=rrSq\
S
   \S'   \R0                  R3                  S5      SL r\ " S S
5      5       r\SS\
\   S\	4S jj5       rS\4S jrS\
\   SS4S jrS\S\S\4S jr S\	S\S\	4S jr!g)zSContains `WebhooksServer` and `webhook_endpoint` to create a webhook server easily.    N)wraps)TYPE_CHECKINGAnyCallableOptional   )experimentalis_fastapi_availableis_gradio_available)Request)FastAPIr   )JSONResponseWebhooksServer_global_appSPACE_IDc                      ^  \ rS rSrSrSU 4S jjr  SS\S   S\\   SS4S	 jjrSS
\\   S\	4S jjr
SS\S\SS4S jjrSS jrSrU =r$ )r   *   a  
The [`WebhooksServer`] class lets you create an instance of a Gradio app that can receive Huggingface webhooks.
These webhooks can be registered using the [`~WebhooksServer.add_webhook`] decorator. Webhook endpoints are added to
the app as a POST endpoint to the FastAPI router. Once all the webhooks are registered, the `launch` method has to be
called to start the app.

It is recommended to accept [`WebhookPayload`] as the first argument of the webhook function. It is a Pydantic
model that contains all the information about the webhook event. The data will be parsed automatically for you.

Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your
WebhooksServer and deploy it on a Space.

> [!WARNING]
> `WebhooksServer` is experimental. Its API is subject to change in the future.

> [!WARNING]
> You must have `gradio` installed to use `WebhooksServer` (`pip install --upgrade gradio`).

Args:
    ui (`gradio.Blocks`, optional):
        A Gradio UI instance to be used as the Space landing page. If `None`, a UI displaying instructions
        about the configured webhooks is created.
    webhook_secret (`str`, optional):
        A secret key to verify incoming webhook requests. You can set this value to any secret you want as long as
        you also configure it in your [webhooks settings panel](https://huggingface.co/settings/webhooks). You
        can also set this value as the `WEBHOOK_SECRET` environment variable. If no secret is provided, the
        webhook endpoints are opened without any security.

Example:

    ```python
    import gradio as gr
    from huggingface_hub import WebhooksServer, WebhookPayload

    with gr.Blocks() as ui:
        ...

    app = WebhooksServer(ui=ui, webhook_secret="my_secret_key")

    @app.add_webhook("/say_hello")
    async def hello(payload: WebhookPayload):
        return {"message": "hello"}

    app.launch()
    ```
returnc                    > [        5       (       d  [        S5      e[        5       (       d  [        S5      e[        TU ]  U 5      $ )NzjYou must have `gradio` installed to use `WebhooksServer`. Please run `pip install --upgrade gradio` first.zlYou must have `fastapi` installed to use `WebhooksServer`. Please run `pip install --upgrade fastapi` first.)r   ImportErrorr
   super__new__)clsargskwargs	__class__s      `/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/huggingface_hub/_webhooks_server.pyr   WebhooksServer.__new__[   sL    "$$  $%%  ws##    Nui	gr.Blockswebhook_secretc                     Xl         U=(       d    [        R                  " S5      U l        0 U l        [        U R                  5        g )NWEBHOOK_SECRET)_uiosgetenvr"   registered_webhooks_warn_on_empty_secret)selfr    r"   s      r   __init__WebhooksServer.__init__h   s6    
 ,K		:J0K8: d112r   pathc                    ^ ^ [        T5      (       a  T R                  5       " T5      $ [        [        R                  5      UU 4S j5       nU$ )a  
Decorator to add a webhook to the [`WebhooksServer`] server.

Args:
    path (`str`, optional):
        The URL path to register the webhook function. If not provided, the function name will be used as the
        path. In any case, all webhooks are registered under `/webhooks`.

Raises:
    ValueError: If the provided path is already registered as a webhook.

Example:
    ```python
    from huggingface_hub import WebhooksServer, WebhookPayload

    app = WebhooksServer()

    @app.add_webhook
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    app.launch()
```
c                     > U S   nST=(       d    UR                   R                  S5       3nUTR                  ;   a  [        SU S35      eUTR                  U'   g )Nr   z
/webhooks//zWebhook z already exists.)__name__stripr(   
ValueError)r   r   funcabs_pathr-   r*   s       r   _inner_post/WebhooksServer.add_webhook.<locals>._inner_post   s`    7D#T%:T]]$A$A#$F#GHH4333 8H:5E!FGG15D$$X.r   )callableadd_webhookr   r   post)r*   r-   r6   s   `` r   r9   WebhooksServer.add_webhooks   sG    8 D>>##%d++ 
w||		6 
	6 r   prevent_thread_locklaunch_kwargsc                   ^	 U R                   =(       d    U R                  5       nUR                  S[        5        UR                  " SSS0UD6u  U l          nU R                  R                  5        HF  u  pVU R                  b  [        X`R                  S9nU R
                  R                  U5      " U5        MH     [        R                  R                  S5      nUb  SU-   OUR                  =(       d    UR                  m	T	c  [!        S5      eT	R#                  S	5      m	S
nUSSR%                  U	4S jU R                   5       5      -   -  nUS-  n['        U5        U(       d  UR)                  5         gg)zLaunch the Gradio app and register webhooks to the underlying FastAPI server.

Input parameters are forwarded to Gradio when launching the app.
sharer<   TNr"   
SPACE_HOSTzhttps://zWCannot find the URL of the app. Please provide a valid `ui` or update `gradio` version.r0   z/
Webhooks are correctly setup and ready to use:
c              3   2   >#    U  H  nS T U 3v   M     g7f)z	  - POST N ).0webhookurls     r   	<genexpr>(WebhooksServer.launch.<locals>.<genexpr>   s     #gNf7iuWI$>Nfs   zG
Go to https://huggingface.co/settings/webhooks to setup your webhooks.rD   )r%   _get_default_ui
setdefault	_is_locallaunchfastapi_appr(   itemsr"   _wrap_webhook_to_check_secretr:   r&   environget	share_url	local_urlr3   r2   joinprintblock_thread)
r*   r<   r=   r    _r-   r4   
space_hostmessagerG   s
            @r   rM   WebhooksServer.launch   sB   
 XX/--/
 	  )4!#!Ut!U}!U!Q 2288:JD"".4TJ]J]^ !!$'- ; ZZ^^L1
)3)?j:%bllFbVXVbVb;vwwiinD4$))#gdNfNf#gggg]]g"OO #r   c           	         SSK nUR                  " 5        nUR                  " S5        UR                  " S5        UR                  " [        U R                  5       S3S-   SR                  S U R                  R                  5        5       5      -   5        UR                  " [        (       a  S	OS
5        SSS5        U$ ! , (       d  f       W$ = f)zLDefault UI if not provided (lists webhooks and provides basic instructions).r   Nu)   # This is an app to process 🤗 WebhooksaT  Webhooks are a foundation for MLOps-related features. They allow you to listen for new changes on specific repos or to all repos belonging to particular set of users/organizations (not just your repos, but any repo). Check out this [guide](https://huggingface.co/docs/hub/webhooks) to get to know more about webhooks on the Huggingface Hub.z webhook(s) are registered:z

z
 c              3   `   #    U  H$  u  pS U S[        UR                  U5       S3v   M&     g7f)z- [z]()N)_get_webhook_doc_urlr1   )rE   webhook_pathrF   s      r   rH   1WebhooksServer._get_default_ui.<locals>.<genexpr>   s:      1Q- ,r*>w?O?OQ]*^)__`a1Qs   ,.zGo to https://huggingface.co/settings/webhooks to setup your webhooks.
You app is running locally. Please look at the logs to check the full URL you need to set.z
This app is running on a Space. You can find the corresponding URL in the options menu (top-right) > 'Embed the Space'. The URL looks like 'https://{username}-{repo_name}.hf.space'.)gradioBlocksMarkdownlenr(   rU   rO   rL   )r*   grr    s      r   rJ   WebhooksServer._get_default_ui   s    YY[BKKCDKKD KKt//011LM** 151I1I1O1O1Q  KK 9qv! 2 	3 [2 	s   B C  
C)r%   rN   r(   r"   )r   r   )NNN)F)r   r!   )r1   
__module____qualname____firstlineno____doc__r   r   strr+   r   r9   boolr   rM   rJ   __static_attributes____classcell__)r   s   @r   r   r   *   s~    -^$ %)(,	3[!	3 !	3 
		3) ) )V"$ " "QU "H r   r-   r   c                    ^  [        T 5      (       a  [        5       " T 5      $ [        [        R                  5      S[
        S[
        4U 4S jj5       nU$ )a  Decorator to start a [`WebhooksServer`] and register the decorated function as a webhook endpoint.

This is a helper to get started quickly. If you need more flexibility (custom landing page or webhook secret),
you can use [`WebhooksServer`] directly. You can register multiple webhook endpoints (to the same server) by using
this decorator multiple times.

Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your
server and deploy it on a Space.

> [!WARNING]
> `webhook_endpoint` is experimental. Its API is subject to change in the future.

> [!WARNING]
> You must have `gradio` installed to use `webhook_endpoint` (`pip install --upgrade gradio`).

Args:
    path (`str`, optional):
        The URL path to register the webhook function. If not provided, the function name will be used as the path.
        In any case, all webhooks are registered under `/webhooks`.

Examples:
    The default usage is to register a function as a webhook endpoint. The function name will be used as the path.
    The server will be started automatically at exit (i.e. at the end of the script).

    ```python
    from huggingface_hub import webhook_endpoint, WebhookPayload

    @webhook_endpoint
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    # Server is automatically started at the end of the script.
    ```

    Advanced usage: register a function as a webhook endpoint and start the server manually. This is useful if you
    are running it in a notebook.

    ```python
    from huggingface_hub import webhook_endpoint, WebhookPayload

    @webhook_endpoint
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    # Start the server manually
    trigger_training.launch()
    ```
r4   r   c                   >^ [        5       mTR                  T5      " U 5        [        TR                  5      S:X  a   [        R
                  " TR                  5        [        TR                  5      U4S j5       nXl        U $ )Nr   c                  f   > [         R                  " T R                  5        T R                  5         g rh   )atexit
unregisterrM   )apps   r   _launch_now5webhook_endpoint.<locals>._inner.<locals>._launch_now$  s      cjj)JJLr   )_get_global_appr9   re   r(   rt   registerrM   r   )r4   rw   rv   r-   s     @r   _inner webhook_endpoint.<locals>._inner  sf    d#s&&'1,OOCJJ'	szz		 
	
 "r   )r8   webhook_endpointr   r   r9   r   )r-   r{   s   ` r   r}   r}      sO    l ~~!$''
>%%&X (  '  Mr   c                  0    [         c
  [        5       q [         $ rh   )r   r   rD   r   r   ry   ry   0  s    $&r   r"   c                 d    U c"  [        S5        [        S5        [        S5        g [        S5        g )NzZWebhook secret is not defined. This means your webhook endpoints will be open to everyone.zTo add a secret, set `WEBHOOK_SECRET` as environment variable or pass it at initialization: 
	`app = WebhooksServer(webhook_secret='my_secret', ...)`zpFor more details about webhook secrets, please refer to https://huggingface.co/docs/hub/webhooks#webhook-secret.z$Webhook secret is correctly defined.)rV   r@   s    r   r)   r)   7  s:    jkJ	
 	H	

 	45r   webhook_namer`   c                 8    SU -   UR                  SS5      -   S-   $ )z@Returns the anchor to a given webhook in the docs (experimental)z/docs#/default/r0   rX   _post)replace)r   r`   s     r   r_   r_   F  s$    |+l.B.B3.LLwVVr   r4   c                 f  ^ ^^ [         R                  " T 5      m[        T 5      S[        4U UU4S jj5       nSTR                  ;  ai  TR                  [         R                  " S[         R                  R                  [        S94[        TR                  R                  5       5      -   S9Ul
        U$ )a  Wraps a webhook function to check the webhook secret before calling the function.

This is a hacky way to add the `request` parameter to the function signature. Since FastAPI based itself on route
parameters to inject the values to the function, we need to hack the function signature to retrieve the `Request`
object (and hence the headers). A far cleaner solution would be to use a middleware. However, since
`fastapi==0.90.1`, a middleware cannot be added once the app has started. And since the FastAPI app is started by
Gradio internals (and not by us), we cannot add a middleware.

This method is called only when a secret has been defined by the user. If a request is sent without the
"x-webhook-secret", the function will return a 401 error (unauthorized). If the header is sent but is incorrect,
the function will return a 403 error (forbidden).

Inspired by https://stackoverflow.com/a/33112180.
requestc                   >#    U R                   R                  S5      nUc  [        SS0SS9$ UT:w  a  [        SS0SS9$ STR                  ;   a  XS'   [        R
                  " T5      (       a  T" S	0 UD6I S h  vN $ T" S	0 UD6$  N7f)
Nzx-webhook-secreterrorz x-webhook-secret header not set.i  )status_codezInvalid webhook secret.i  r   rD   )headersrR   r   
parametersinspectiscoroutinefunction)r   r   request_secretr4   initial_sigr"   s      r   _protected_func6_wrap_webhook_to_check_secret.<locals>._protected_func\  s      ,,-?@!*L M[^__^+*C DRUVV ... '9 &&t,,''>&>! (s   A7B	:B;B	)namekind
annotation)r   )r   	signaturer   r   r   r   	ParameterPOSITIONAL_OR_KEYWORDtuplevalues__signature__)r4   r"   r   r   s   `` @r   rP   rP   K  s     ##D)K
4["w " " "$ ...(3(;(;!!yw7H7H7^7^krs K**11345 )< )
% r   rh   )"rl   rt   r   r&   	functoolsr   typingr   r   r   r   utilsr	   r
   r   rb   rf   fastapir   r   fastapi.responsesr   r   __annotations__rQ   rR   rL   r   rm   r}   ry   r)   r_   rP   rD   r   r   <module>r      s   Z   	  9 9 J J (. (,+G+g +/X&' .JJNN:&$.	 t t tn J8C= JH J JZ 6(3- 6D 6Ws W# W# W
- -# -( -r   