
    HTh=                        % 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
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'   \R2                  R5                  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Dict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 setup your
WebhooksServer and deploy it on a Space.

<Tip warning={true}>

`WebhooksServer` is experimental. Its API is subject to change in the future.

</Tip>

<Tip warning={true}>

You must have `gradio` installed to use `WebhooksServer` (`pip install --upgrade gradio`).

</Tip>

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      X/var/www/auris/envauris/lib/python3.13/site-packages/huggingface_hub/_webhooks_server.pyr   WebhooksServer.__new__a   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__n   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.   r7   s   `` r   r:   WebhooksServer.add_webhooky   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.r1   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.rE   )r&   _get_default_ui
setdefault	_is_locallaunchfastapi_appr)   itemsr#   _wrap_webhook_to_check_secretr;   r'   environget	share_url	local_urlr4   r3   joinprintblock_thread)
r+   r=   r>   r!   _r.   r5   
space_hostmessagerH   s
            @r   rN   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_urlr2   )rF   webhook_pathrG   s      r   rI   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)   rV   rP   rM   )r+   grr!   s      r   rK   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&   rO   r)   r#   )r   r   )NNN)F)r   r"   )r2   
__module____qualname____firstlineno____doc__r   r   strr,   r   r:   boolr   rN   rK   __static_attributes____classcell__)r   s   @r   r   r   *   s~    3j$ %)(,	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 setup your
server and deploy it on a Space.

<Tip warning={true}>

`webhook_endpoint` is experimental. Its API is subject to change in the future.

</Tip>

<Tip warning={true}>

You must have `gradio` installed to use `webhook_endpoint` (`pip install --upgrade gradio`).

</Tip>

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()
    ```
r5   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 ri   )atexit
unregisterrN   )apps   r   _launch_now5webhook_endpoint.<locals>._inner.<locals>._launch_now0  s      cjj)JJLr    )_get_global_appr:   rf   r)   ru   registerrN   r   )r5   rx   rw   r.   s     @r   _inner webhook_endpoint.<locals>._inner(  sf    d#s&&'1,OOCJJ'	szz		 
	
 "r    )r9   webhook_endpointr   r   r:   r   )r.   r|   s   ` r   r~   r~      sO    x ~~!$''
>%%&X (  '  Mr    c                  0    [         c
  [        5       q [         $ ri   )r   r   rE   r    r   rz   rz   <  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.)rW   rA   s    r   r*   r*   C  s:    jkJ	
 	H	

 	45r    webhook_namera   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/r1   rY   _post)replace)r   ra   s     r   r`   r`   R  s$    |+l.B.B3.LLwVVr    r5   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   rE   )headersrS   r   
parametersinspectiscoroutinefunction)r   r   request_secretr5   initial_sigr#   s      r   _protected_func6_wrap_webhook_to_check_secret.<locals>._protected_funch  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__)r5   r#   r   r   s   `` @r   rQ   rQ   W  s     ##D)K
4["w " " "$ ...(3(;(;!!yw7H7H7^7^krs K**11345 )< )
% r    ri   )#rm   ru   r   r'   	functoolsr   typingr   r   r   r   r   utilsr
   r   r   rc   rg   fastapir   r   fastapi.responsesr   r   __annotations__rR   rS   rM   r   rn   r~   rz   r*   r`   rQ   rE   r    r   <module>r      s   Z   	  ? ? J J (. (,+G+g +/X&' .JJNN:&$.	 z z zz P8C= PH P Pf 6(3- 6D 6Ws W# W# W
- -# -( -r    