import{s as Ml,o as Ul,n as He}from"../chunks/scheduler.6062bdaf.js";import{S as rl,i as cl,g as p,s as a,r,A as hl,h as i,f as s,c as n,j as il,u as c,x as U,k as We,y as yl,a as t,v as h,d as y,t as d,w}from"../chunks/index.4bca734e.js";import{T as Ge}from"../chunks/Tip.b9ac1f03.js";import{C as se}from"../chunks/CodeBlock.fa01571c.js";import{H as ee,E as dl}from"../chunks/EditOnGithub.74ab2baa.js";function wl(g){let o,f=`웹훅 서버의 실행 예시를 보려면 <a href="https://huggingface.co/spaces/spaces-ci-bot/webhook" rel="nofollow">Spaces CI Bot</a>을 확인하세요.
이것은 Space의 PR이 열릴 때마다 임시 환경을 실행하는 Space입니다.`;return{c(){o=p("p"),o.innerHTML=f},l(M){o=i(M,"P",{"data-svelte-h":!0}),U(o)!=="svelte-x9rigv"&&(o.innerHTML=f)},m(M,b){t(M,o,b)},p:He,d(M){M&&s(o)}}}function fl(g){let o,f=`이것은 <a href="../package_reference/environment_variables#hfhubdisableexperimentalwarning">실험적 기능</a>입니다.
본 API는 현재 개선 작업 중이며, 향후 사전 통지 없이 주요 변경 사항이 도입될 수 있습니다.
requirements에서 <code>huggingface_hub</code>의 버전을 고정하는 것을 권장합니다.`;return{c(){o=p("p"),o.innerHTML=f},l(M){o=i(M,"P",{"data-svelte-h":!0}),U(o)!=="svelte-10q23mi"&&(o.innerHTML=f)},m(M,b){t(M,o,b)},p:He,d(M){M&&s(o)}}}function bl(g){let o,f=`기본적으로 서버는 스크립트 끝에서 시작됩니다.
주피터 노트북에서 실행 중이라면 <code>decorated_function.run()</code>을 호출하여 서버를 수동으로 시작할 수 있습니다.
고유한 서버를 사용하기 때문에 여러 엔드포인트가 있더라도 서버를 한 번만 시작하면 됩니다.`;return{c(){o=p("p"),o.innerHTML=f},l(M){o=i(M,"P",{"data-svelte-h":!0}),U(o)!=="svelte-j9jjbb"&&(o.innerHTML=f)},m(M,b){t(M,o,b)},p:He,d(M){M&&s(o)}}}function gl(g){let o,f,M,b,j,te,T,Ne=`웹훅은 MLOps 관련 기능의 기반이 됩니다. 이를 통해 특정 저장소의 새로운 변경 사항을 수신하거나,
관심 있는 특정 사용자/조직에 속한 모든 저장소의 변경 사항을 받아볼 수 있습니다.
이 가이드에서는 <code>huggingface_hub</code>를 활용하여 웹훅을 수신하는 서버를 만들고 Space에 배포하는 방법을 설명합니다.
이를 위해서는 Huggingface Hub의 웹훅 개념에 대해 익숙해야 합니다.
웹훅 자체에 대해 더 자세히 알아보려면 이 <a href="https://huggingface.co/docs/hub/webhooks" rel="nofollow">가이드</a>를 먼저 읽어보세요.`,ae,V,Ee=`이 가이드에서 사용할 기본 클래스는 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a>입니다.
이 클래스는 Huggingface Hub에서 웹훅을 받을 수 있는 서버를 쉽게 구성할 수 있습니다. 서버는 <a href="https://gradio.app/" rel="nofollow">Gradio</a> 앱을 기반으로 합니다.
이 서버에는 사용자를 위한 지침을 표시하는 UI와 웹훅을 수신하는 API가 있습니다.`,ne,C,oe,J,pe,k,ie,Q,Ye=`웹훅 엔드포인트를 구현하는 것은 함수에 데코레이터를 추가하는 것만큼 간단합니다.
주요 개념을 설명하기 위해 첫 번째 예시를 살펴보겠습니다:`,Me,$,Ue,v,Oe="이 코드 스니펫을 <code>&#39;app.py&#39;</code>라는 파일에 저장하고 <code>&#39;python app.py&#39;</code>로 실행하면 다음과 같은 메시지가 표시될 것입니다:",re,S,ce,I,Le="축하합니다! 웹훅 서버를 실행했습니다! 정확히 어떤 일이 일어났는지 살펴보겠습니다:",he,F,Ae=`<li><a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.webhook_endpoint">webhook_endpoint()</a>로 함수에 데코레이터를 추가하면 백그라운드에서 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a> 객체가 생성됩니다.
볼 수 있듯이 이 서버는 <a href="http://127.0.0.1:7860" rel="nofollow">http://127.0.0.1:7860</a> 에서 실행되는 Gradio 앱입니다.
이 URL을 브라우저에서 열면 등록된 웹훅에 대한 지침이 있는 랜딩 페이지를 볼 수 있습니다.</li> <li>Gradio 앱은 내부적으로 FastAPI 서버입니다. 새로운 POST 경로 <code>/webhooks/trigger_training</code>이 추가되었습니다.
이 경로는 웹훅을 수신하고 트리거될 때 <code>trigger_training</code> 함수를 실행합니다.
FastAPI는 자동으로 페이로드를 구문 분석하고 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhookPayload">WebhookPayload</a> 객체로 함수에 전달합니다.
이 <code>pydantic</code> 객체에는 웹훅을 트리거한 이벤트에 대한 모든 정보가 포함되어 있습니다.</li> <li>Gradio 앱은 인터넷에서 요청을 받을 수 있는 터널도 열었습니다.
이것은 흥미로운 부분으로, <a href="https://huggingface.co/settings/webhooks" rel="nofollow">https://huggingface.co/settings/webhooks</a> 에서 로컬 머신을 가리키는 웹훅을 구성할 수 있습니다.
이를 통해 웹훅 서버를 디버깅하고 Space에 배포하기 전에 빠르게 반복할 수 있습니다.</li> <li>마지막으로 로그에는 서버가 현재 비밀로 보호되지 않는다고 알려줍니다.
이것은 로컬 디버깅에는 문제가 되지 않지만 나중에 고려해야 할 사항입니다.</li>`,ye,m,de,_,we,Z,Xe=`웹훅 서버를 실행하고 있으므로, 이제 메시지를 수신하기 위해 웹훅을 구성해야 합니다.
<a href="https://huggingface.co/settings/webhooks" rel="nofollow">https://huggingface.co/settings/webhooks</a> 로 이동하여 “Add a new webhook”을 클릭하고 웹훅을 구성하세요.
모니터링할 대상 저장소와 웹훅 URL <code>https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training</code>을 설정하세요.`,fe,u,xe='<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/configure_webhook.png"/>',be,B,ze=`이걸로 끝입니다! 이제 대상 저장소를 업데이트하면 웹훅을 트리거할 수 있습니다. 예를 들면, 커밋 푸시가 그 방법이 될 수 있습니다.
웹훅의 Activity 탭에서 트리거된 이벤트를 확인할 수 있습니다. 이제 작동하는 구성이 있으므로 테스트하고 빠르게 반복할 수 있습니다.
코드를 수정하고 서버를 다시 시작하면 공개 URL이 변경될 수 있습니다.
필요한 경우 Hub에서 웹훅 구성을 업데이트하세요.`,ge,R,Ce,W,Pe=`이제 작동하는 웹훅 서버가 마련되었으므로, 다음 목표는 이를 Space에 배포하는 것입니다. <a href="https://huggingface.co/new-space" rel="nofollow">https://huggingface.co/new-space</a> 에 가서 Space를 생성합니다.
이름을 지정하고, Gradio SDK를 선택한 다음 “Create Space”를 클릭합니다. 코드를 <code>app.py</code> 파일로 Space에 업로드합니다.
Space가 자동으로 시작됩니다!
Space에 대한 자세한 내용은 이 <a href="https://huggingface.co/docs/hub/spaces-overview" rel="nofollow">가이드</a>를 참조하세요.`,Je,G,De=`웹훅 서버가 이제 공개 Space에서 실행 중입니다. 대부분의 경우 비밀번호로 보안을 설정하고 싶을 것입니다.
Space 설정 &gt; “Repository secrets” 섹션 &gt; “Add a secret” 로 이동합니다. <code>WEBHOOK_SECRET</code> 환경 변수에 원하는 값을 설정합니다.
<a href="https://huggingface.co/settings/webhooks" rel="nofollow">Webhooks 설정</a>으로 돌아가서 웹훅 구성에 비밀번호를 설정합니다.
이제 올바른 비밀번호가 있는 요청만 서버에서 허용됩니다.`,me,H,qe=`이게 전부입니다! Space가 이제 Hub의 웹훅을 수신할 준비가 되었습니다.
무료 하드웨어인 ‘cpu-basic’에서 Space를 실행 시, 48시간 동안 비활성화되면 종료된다는 점을 유념하세요.
영구적인 Space가 필요한 경우 <a href="https://huggingface.co/docs/hub/spaces-gpus#hardware-specs" rel="nofollow">업그레이드된 하드웨어</a>를 설정해야 합니다.`,ue,N,je,E,Ke=`위의 가이드에서는 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a>를 설정하는 가장 빠른 방법에 대해 설명했습니다.
이 섹션에서는 이를 더욱 사용자 정의하는 방법을 살펴보겠습니다.`,Te,Y,Ve,O,el=`동일한 서버에 여러 엔드포인트를 등록할 수 있습니다.
예를 들어, 하나의 엔드포인트는 학습 작업을 트리거하고 다른 엔드포인트는 모델 평가를 트리거하도록 할 수 있습니다.
이를 위해 여러 개의 <code>@webhook_endpoint</code> 데코레이터를 추가하면 됩니다:`,ke,L,Qe,A,ll="이렇게 하면 두 개의 엔드포인트가 생성됩니다:",$e,X,ve,x,Se,z,sl=`더 많은 유연성을 얻기 위해 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a> 객체를 직접 생성할 수도 있습니다.
이것은 서버의 랜딩 페이지를 사용자 정의하고자 할 때 유용합니다.
기본 페이지를 덮어쓸 <a href="https://gradio.app/docs/#blocks" rel="nofollow">Gradio UI</a>를 전달하여 이를 수행할 수 있습니다.
예를 들어, 사용자를 위한 지침을 추가하거나 웹훅을 수동으로 트리거하는 양식을 추가할 수 있습니다.
<a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a>를 생성할 때, <code>add_webhook()</code> 데코레이터를 사용하여 새로운 웹훅을 등록할 수 있습니다.`,Ie,P,tl="전체 예제는 다음과 같습니다:",Fe,D,_e,q,al=`<li>Gradio 블록을 사용하여 사용자 정의 UI를 정의합니다. 이 UI는 서버의 랜딩 페이지에 표시됩니다.</li> <li>사용자 정의 UI와 시크릿으로 <a href="/docs/huggingface_hub/pr_2367/ko/package_reference/webhooks_server#huggingface_hub.WebhooksServer">WebhooksServer()</a> 객체를 생성합니다.
시크릿은 선택 사항이며 <code>WEBHOOK_SECRET</code> 환경 변수로 설정할 수 있습니다.</li> <li>명시적 이름으로 웹훅을 등록합니다. 이렇게 하면 <code>/webhooks/say_hello</code> 엔드포인트가 생성됩니다.</li> <li>암시적 이름으로 웹훅을 등록합니다. 이렇게 하면 <code>/webhooks/goodbye</code> 엔드포인트가 생성됩니다.</li> <li>서버를 시작합니다. 이것은 선택 사항이며 스크립트 끝에서 자동으로 서버가 시작됩니다.</li>`,Ze,K,Be,le,Re;return j=new ee({props:{title:"웹훅 서버",local:"webhooks-server",headingTag:"h1"}}),C=new Ge({props:{$$slots:{default:[wl]},$$scope:{ctx:g}}}),J=new Ge({props:{warning:!0,$$slots:{default:[fl]},$$scope:{ctx:g}}}),k=new ee({props:{title:"엔드포인트 생성",local:"create-an-endpoint",headingTag:"h2"}}),$=new se({props:{code:"JTIzJTIwYXBwLnB5JTBBZnJvbSUyMGh1Z2dpbmdmYWNlX2h1YiUyMGltcG9ydCUyMHdlYmhvb2tfZW5kcG9pbnQlMkMlMjBXZWJob29rUGF5bG9hZCUwQSUwQSU0MHdlYmhvb2tfZW5kcG9pbnQlMEFhc3luYyUyMGRlZiUyMHRyaWdnZXJfdHJhaW5pbmcocGF5bG9hZCUzQSUyMFdlYmhvb2tQYXlsb2FkKSUyMC0lM0UlMjBOb25lJTNBJTBBJTIwJTIwJTIwJTIwaWYlMjBwYXlsb2FkLnJlcG8udHlwZSUyMCUzRCUzRCUyMCUyMmRhdGFzZXQlMjIlMjBhbmQlMjBwYXlsb2FkLmV2ZW50LmFjdGlvbiUyMCUzRCUzRCUyMCUyMnVwZGF0ZSUyMiUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMCVFQiU4RCVCMCVFQyU5RCVCNCVFRCU4NCVCMCUyMCVFQyU4NCVCOCVFRCU4QSVCOCVFQSVCMCU4MCUyMCVFQyU5NyU4NSVFQiU4RCVCMCVFQyU5RCVCNCVFRCU4QSVCOCVFQiU5MCU5OCVFQiVBOSVCNCUyMCVFRCU5NSU5OSVFQyU4QSVCNSUyMCVFQyU5RSU5MSVFQyU5NyU4NSVFQyU5RCU4NCUyMCVFRCU4QSVCOCVFQiVBNiVBQyVFQSVCMSVCMCVFRCU5NSVBOSVFQiU4QiU4OCVFQiU4QiVBNC4lMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAuLi4=",highlighted:`<span class="hljs-comment"># app.py</span>
<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> webhook_endpoint, WebhookPayload

<span class="hljs-meta">@webhook_endpoint</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trigger_training</span>(<span class="hljs-params">payload: WebhookPayload</span>) -&gt; <span class="hljs-literal">None</span>:
    <span class="hljs-keyword">if</span> payload.repo.<span class="hljs-built_in">type</span> == <span class="hljs-string">&quot;dataset&quot;</span> <span class="hljs-keyword">and</span> payload.event.action == <span class="hljs-string">&quot;update&quot;</span>:
        <span class="hljs-comment"># 데이터 세트가 업데이트되면 학습 작업을 트리거합니다.</span>
        ...`,wrap:!1}}),S=new se({props:{code:"V2ViaG9vayUyMHNlY3JldCUyMGlzJTIwbm90JTIwZGVmaW5lZC4lMjBUaGlzJTIwbWVhbnMlMjB5b3VyJTIwd2ViaG9vayUyMGVuZHBvaW50cyUyMHdpbGwlMjBiZSUyMG9wZW4lMjB0byUyMGV2ZXJ5b25lLiUwQVRvJTIwYWRkJTIwYSUyMHNlY3JldCUyQyUyMHNldCUyMCU2MFdFQkhPT0tfU0VDUkVUJTYwJTIwYXMlMjBlbnZpcm9ubWVudCUyMHZhcmlhYmxlJTIwb3IlMjBwYXNzJTIwaXQlMjBhdCUyMGluaXRpYWxpemF0aW9uJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTYwYXBwJTIwJTNEJTIwV2ViaG9va3NTZXJ2ZXIod2ViaG9va19zZWNyZXQlM0QnbXlfc2VjcmV0JyUyQyUyMC4uLiklNjAlMEFGb3IlMjBtb3JlJTIwZGV0YWlscyUyMGFib3V0JTIwd2ViaG9vayUyMHNlY3JldHMlMkMlMjBwbGVhc2UlMjByZWZlciUyMHRvJTIwaHR0cHMlM0ElMkYlMkZodWdnaW5nZmFjZS5jbyUyRmRvY3MlMkZodWIlMkZ3ZWJob29rcyUyM3dlYmhvb2stc2VjcmV0LiUwQVJ1bm5pbmclMjBvbiUyMGxvY2FsJTIwVVJMJTNBJTIwJTIwaHR0cCUzQSUyRiUyRjEyNy4wLjAuMSUzQTc4NjAlMEFSdW5uaW5nJTIwb24lMjBwdWJsaWMlMjBVUkwlM0ElMjBodHRwcyUzQSUyRiUyRjFmYWRiMGY1MmQ4YmY4MjVmYy5ncmFkaW8ubGl2ZSUwQSUwQVRoaXMlMjBzaGFyZSUyMGxpbmslMjBleHBpcmVzJTIwaW4lMjA3MiUyMGhvdXJzLiUyMEZvciUyMGZyZWUlMjBwZXJtYW5lbnQlMjBob3N0aW5nJTIwYW5kJTIwR1BVJTIwdXBncmFkZXMlMjAoTkVXISklMkMlMjBjaGVjayUyMG91dCUyMFNwYWNlcyUzQSUyMGh0dHBzJTNBJTJGJTJGaHVnZ2luZ2ZhY2UuY28lMkZzcGFjZXMlMEElMEFXZWJob29rcyUyMGFyZSUyMGNvcnJlY3RseSUyMHNldHVwJTIwYW5kJTIwcmVhZHklMjB0byUyMHVzZSUzQSUwQSUyMCUyMC0lMjBQT1NUJTIwaHR0cHMlM0ElMkYlMkYxZmFkYjBmNTJkOGJmODI1ZmMuZ3JhZGlvLmxpdmUlMkZ3ZWJob29rcyUyRnRyaWdnZXJfdHJhaW5pbmclMEFHbyUyMHRvJTIwaHR0cHMlM0ElMkYlMkZodWdnaW5nZmFjZS5jbyUyRnNldHRpbmdzJTJGd2ViaG9va3MlMjB0byUyMHNldHVwJTIweW91ciUyMHdlYmhvb2tzLg==",highlighted:`Webhook secret is not defined. This means your webhook endpoints will be open to everyone.
To add a secret, set \`WEBHOOK_SECRET\` as environment variable or pass it at initialization:
        \`app = WebhooksServer(webhook_secret=&#x27;my_secret&#x27;, ...)\`
For more details about webhook secrets, please refer to https://huggingface.co/docs/hub/webhooks#webhook-secret.
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://1fadb0f52d8bf825fc.gradio.live

This share link expires in 72 hours. For free permanent hosting and GPU upgrades (NEW!), check out Spaces: https://huggingface.co/spaces

Webhooks are correctly setup and ready to use:
  - POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training
Go to https://huggingface.co/settings/webhooks to setup your webhooks.`,wrap:!1}}),m=new Ge({props:{warning:!0,$$slots:{default:[bl]},$$scope:{ctx:g}}}),_=new ee({props:{title:"웹훅 설정하기",local:"configure-a-webhook",headingTag:"h2"}}),R=new ee({props:{title:"Space에 배포하기",local:"deploy-to-a-space",headingTag:"h2"}}),N=new ee({props:{title:"고급 사용법",local:"advanced-usage",headingTag:"h2"}}),Y=new ee({props:{title:"다중 엔드포인트",local:"multiple-endpoints",headingTag:"h3"}}),L=new se({props:{code:"JTIzJTIwYXBwLnB5JTBBZnJvbSUyMGh1Z2dpbmdmYWNlX2h1YiUyMGltcG9ydCUyMHdlYmhvb2tfZW5kcG9pbnQlMkMlMjBXZWJob29rUGF5bG9hZCUwQSUwQSU0MHdlYmhvb2tfZW5kcG9pbnQlMEFhc3luYyUyMGRlZiUyMHRyaWdnZXJfdHJhaW5pbmcocGF5bG9hZCUzQSUyMFdlYmhvb2tQYXlsb2FkKSUyMC0lM0UlMjBOb25lJTNBJTBBJTIwJTIwJTIwJTIwaWYlMjBwYXlsb2FkLnJlcG8udHlwZSUyMCUzRCUzRCUyMCUyMmRhdGFzZXQlMjIlMjBhbmQlMjBwYXlsb2FkLmV2ZW50LmFjdGlvbiUyMCUzRCUzRCUyMCUyMnVwZGF0ZSUyMiUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMCVFQiU4RCVCMCVFQyU5RCVCNCVFRCU4NCVCMCUyMCVFQyU4NCVCOCVFRCU4QSVCOCVFQSVCMCU4MCUyMCVFQyU5NyU4NSVFQiU4RCVCMCVFQyU5RCVCNCVFRCU4QSVCOCVFQiU5MCU5OCVFQiVBOSVCNCUyMCVFRCU5NSU5OSVFQyU4QSVCNSUyMCVFQyU5RSU5MSVFQyU5NyU4NSVFQyU5RCU4NCUyMCVFRCU4QSVCOCVFQiVBNiVBQyVFQSVCMSVCMCVFRCU5NSVBOSVFQiU4QiU4OCVFQiU4QiVBNC4lMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAuLi4lMEElMEElNDB3ZWJob29rX2VuZHBvaW50JTBBYXN5bmMlMjBkZWYlMjB0cmlnZ2VyX2V2YWx1YXRpb24ocGF5bG9hZCUzQSUyMFdlYmhvb2tQYXlsb2FkKSUyMC0lM0UlMjBOb25lJTNBJTBBJTIwJTIwJTIwJTIwaWYlMjBwYXlsb2FkLnJlcG8udHlwZSUyMCUzRCUzRCUyMCUyMm1vZGVsJTIyJTIwYW5kJTIwcGF5bG9hZC5ldmVudC5hY3Rpb24lMjAlM0QlM0QlMjAlMjJ1cGRhdGUlMjIlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjAlRUIlQUElQTglRUIlOEQlQjglRUMlOUQlQjQlMjAlRUMlOTclODUlRUIlOEQlQjAlRUMlOUQlQjQlRUQlOEElQjglRUIlOTAlOTglRUIlQTklQjQlMjAlRUQlOEYlODklRUElQjAlODAlMjAlRUMlOUUlOTElRUMlOTclODUlRUMlOUQlODQlMjAlRUQlOEElQjglRUIlQTYlQUMlRUElQjElQjAlRUQlOTUlQTklRUIlOEIlODglRUIlOEIlQTQuJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwLi4u",highlighted:`<span class="hljs-comment"># app.py</span>
<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> webhook_endpoint, WebhookPayload

<span class="hljs-meta">@webhook_endpoint</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trigger_training</span>(<span class="hljs-params">payload: WebhookPayload</span>) -&gt; <span class="hljs-literal">None</span>:
    <span class="hljs-keyword">if</span> payload.repo.<span class="hljs-built_in">type</span> == <span class="hljs-string">&quot;dataset&quot;</span> <span class="hljs-keyword">and</span> payload.event.action == <span class="hljs-string">&quot;update&quot;</span>:
        <span class="hljs-comment"># 데이터 세트가 업데이트되면 학습 작업을 트리거합니다.</span>
        ...

<span class="hljs-meta">@webhook_endpoint</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">trigger_evaluation</span>(<span class="hljs-params">payload: WebhookPayload</span>) -&gt; <span class="hljs-literal">None</span>:
    <span class="hljs-keyword">if</span> payload.repo.<span class="hljs-built_in">type</span> == <span class="hljs-string">&quot;model&quot;</span> <span class="hljs-keyword">and</span> payload.event.action == <span class="hljs-string">&quot;update&quot;</span>:
        <span class="hljs-comment"># 모델이 업데이트되면 평가 작업을 트리거합니다. </span>
        ...`,wrap:!1}}),X=new se({props:{code:"KC4uLiklMEFXZWJob29rcyUyMGFyZSUyMGNvcnJlY3RseSUyMHNldHVwJTIwYW5kJTIwcmVhZHklMjB0byUyMHVzZSUzQSUwQSUyMCUyMC0lMjBQT1NUJTIwaHR0cHMlM0ElMkYlMkYxZmFkYjBmNTJkOGJmODI1ZmMuZ3JhZGlvLmxpdmUlMkZ3ZWJob29rcyUyRnRyaWdnZXJfdHJhaW5pbmclMEElMjAlMjAtJTIwUE9TVCUyMGh0dHBzJTNBJTJGJTJGMWZhZGIwZjUyZDhiZjgyNWZjLmdyYWRpby5saXZlJTJGd2ViaG9va3MlMkZ0cmlnZ2VyX2V2YWx1YXRpb24=",highlighted:`(...)
Webhooks are correctly setup and ready to use:
  - POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training
  - POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_evaluation`,wrap:!1}}),x=new ee({props:{title:"사용자 정의 서버",local:"custom-server",headingTag:"h3"}}),D=new se({props:{code:"aW1wb3J0JTIwZ3JhZGlvJTIwYXMlMjBnciUwQWZyb20lMjBmYXN0YXBpJTIwaW1wb3J0JTIwUmVxdWVzdCUwQWZyb20lMjBodWdnaW5nZmFjZV9odWIlMjBpbXBvcnQlMjBXZWJob29rc1NlcnZlciUyQyUyMFdlYmhvb2tQYXlsb2FkJTBBJTBBJTIzJTIwMS4lMjBVSSUyMCVFQyVBMCU5NSVFQyU5RCU5OCUwQXdpdGglMjBnci5CbG9ja3MoKSUyMGFzJTIwdWklM0ElMEElMjAlMjAlMjAlMjAuLi4lMEElMEElMjMlMjAyLiUyMCVFQyU4MiVBQyVFQyU5QSVBOSVFQyU5RSU5MCUyMCVFQyVBMCU5NSVFQyU5RCU5OCUyMFVJJUVDJTk5JTgwJTIwJUVDJThCJTlDJUVEJTgxJUFDJUVCJUE2JUJGJUVDJTlDJUJDJUVCJUExJTlDJTIwV2ViaG9va3NTZXJ2ZXIlMjAlRUMlODMlOUQlRUMlODQlQjElMEFhcHAlMjAlM0QlMjBXZWJob29rc1NlcnZlcih1aSUzRHVpJTJDJTIwd2ViaG9va19zZWNyZXQlM0QlMjJteV9zZWNyZXRfa2V5JTIyKSUwQSUwQSUyMyUyMDMuJTIwJUVCJUFBJTg1JUVDJThCJTlDJUVDJUEwJTgxJTIwJUVDJTlEJUI0JUVCJUE2JTg0JUVDJTlDJUJDJUVCJUExJTlDJTIwJUVDJTlCJUI5JUVEJTlCJTg1JTIwJUVCJTkzJUIxJUVCJUExJTlEJTBBJTQwYXBwLmFkZF93ZWJob29rKCUyMiUyRnNheV9oZWxsbyUyMiklMEFhc3luYyUyMGRlZiUyMGhlbGxvKHBheWxvYWQlM0ElMjBXZWJob29rUGF5bG9hZCklM0ElMEElMjAlMjAlMjAlMjByZXR1cm4lMjAlN0IlMjJtZXNzYWdlJTIyJTNBJTIwJTIyaGVsbG8lMjIlN0QlMEElMEElMjMlMjA0LiUyMCVFQyU5NSU5NCVFQyU4QiU5QyVFQyVBMCU4MSUyMCVFQyU5RCVCNCVFQiVBNiU4NCVFQyU5QyVCQyVFQiVBMSU5QyUyMCVFQyU5QiVCOSVFRCU5QiU4NSUyMCVFQiU5MyVCMSVFQiVBMSU5RCUwQSU0MGFwcC5hZGRfd2ViaG9vayUwQWFzeW5jJTIwZGVmJTIwZ29vZGJ5ZShwYXlsb2FkJTNBJTIwV2ViaG9va1BheWxvYWQpJTNBJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwJTdCJTIybWVzc2FnZSUyMiUzQSUyMCUyMmdvb2RieWUlMjIlN0QlMEElMEElMjMlMjA1LiUyMCVFQyU4NCU5QyVFQiVCMiU4NCUyMCVFQyU4QiU5QyVFQyU5RSU5MSUyMCglRUMlODQlQTAlRUQlODMlOUQlMjAlRUMlODIlQUMlRUQlOTUlQUQpJTBBYXBwLnJ1bigp",highlighted:`<span class="hljs-keyword">import</span> gradio <span class="hljs-keyword">as</span> gr
<span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> Request
<span class="hljs-keyword">from</span> huggingface_hub <span class="hljs-keyword">import</span> WebhooksServer, WebhookPayload

<span class="hljs-comment"># 1. UI 정의</span>
<span class="hljs-keyword">with</span> gr.Blocks() <span class="hljs-keyword">as</span> ui:
    ...

<span class="hljs-comment"># 2. 사용자 정의 UI와 시크릿으로 WebhooksServer 생성</span>
app = WebhooksServer(ui=ui, webhook_secret=<span class="hljs-string">&quot;my_secret_key&quot;</span>)

<span class="hljs-comment"># 3. 명시적 이름으로 웹훅 등록</span>
<span class="hljs-meta">@app.add_webhook(<span class="hljs-params"><span class="hljs-string">&quot;/say_hello&quot;</span></span>)</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">hello</span>(<span class="hljs-params">payload: WebhookPayload</span>):
    <span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;message&quot;</span>: <span class="hljs-string">&quot;hello&quot;</span>}

<span class="hljs-comment"># 4. 암시적 이름으로 웹훅 등록</span>
<span class="hljs-meta">@app.add_webhook</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">goodbye</span>(<span class="hljs-params">payload: WebhookPayload</span>):
    <span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;message&quot;</span>: <span class="hljs-string">&quot;goodbye&quot;</span>}

<span class="hljs-comment"># 5. 서버 시작 (선택 사항)</span>
app.run()`,wrap:!1}}),K=new dl({props:{source:"https://github.com/huggingface/huggingface_hub/blob/main/docs/source/ko/guides/webhooks_server.md"}}),{c(){o=p("meta"),f=a(),M=p("p"),b=a(),r(j.$$.fragment),te=a(),T=p("p"),T.innerHTML=Ne,ae=a(),V=p("p"),V.innerHTML=Ee,ne=a(),r(C.$$.fragment),oe=a(),r(J.$$.fragment),pe=a(),r(k.$$.fragment),ie=a(),Q=p("p"),Q.textContent=Ye,Me=a(),r($.$$.fragment),Ue=a(),v=p("p"),v.innerHTML=Oe,re=a(),r(S.$$.fragment),ce=a(),I=p("p"),I.textContent=Le,he=a(),F=p("ol"),F.innerHTML=Ae,ye=a(),r(m.$$.fragment),de=a(),r(_.$$.fragment),we=a(),Z=p("p"),Z.innerHTML=Xe,fe=a(),u=p("div"),u.innerHTML=xe,be=a(),B=p("p"),B.textContent=ze,ge=a(),r(R.$$.fragment),Ce=a(),W=p("p"),W.innerHTML=Pe,Je=a(),G=p("p"),G.innerHTML=De,me=a(),H=p("p"),H.innerHTML=qe,ue=a(),r(N.$$.fragment),je=a(),E=p("p"),E.innerHTML=Ke,Te=a(),r(Y.$$.fragment),Ve=a(),O=p("p"),O.innerHTML=el,ke=a(),r(L.$$.fragment),Qe=a(),A=p("p"),A.textContent=ll,$e=a(),r(X.$$.fragment),ve=a(),r(x.$$.fragment),Se=a(),z=p("p"),z.innerHTML=sl,Ie=a(),P=p("p"),P.textContent=tl,Fe=a(),r(D.$$.fragment),_e=a(),q=p("ol"),q.innerHTML=al,Ze=a(),r(K.$$.fragment),Be=a(),le=p("p"),this.h()},l(e){const l=hl("svelte-u9bgzb",document.head);o=i(l,"META",{name:!0,content:!0}),l.forEach(s),f=n(e),M=i(e,"P",{}),il(M).forEach(s),b=n(e),c(j.$$.fragment,e),te=n(e),T=i(e,"P",{"data-svelte-h":!0}),U(T)!=="svelte-4gg1j0"&&(T.innerHTML=Ne),ae=n(e),V=i(e,"P",{"data-svelte-h":!0}),U(V)!=="svelte-wqj0hs"&&(V.innerHTML=Ee),ne=n(e),c(C.$$.fragment,e),oe=n(e),c(J.$$.fragment,e),pe=n(e),c(k.$$.fragment,e),ie=n(e),Q=i(e,"P",{"data-svelte-h":!0}),U(Q)!=="svelte-127cxas"&&(Q.textContent=Ye),Me=n(e),c($.$$.fragment,e),Ue=n(e),v=i(e,"P",{"data-svelte-h":!0}),U(v)!=="svelte-1tktkge"&&(v.innerHTML=Oe),re=n(e),c(S.$$.fragment,e),ce=n(e),I=i(e,"P",{"data-svelte-h":!0}),U(I)!=="svelte-115owcb"&&(I.textContent=Le),he=n(e),F=i(e,"OL",{"data-svelte-h":!0}),U(F)!=="svelte-1xrk4ue"&&(F.innerHTML=Ae),ye=n(e),c(m.$$.fragment,e),de=n(e),c(_.$$.fragment,e),we=n(e),Z=i(e,"P",{"data-svelte-h":!0}),U(Z)!=="svelte-1470z52"&&(Z.innerHTML=Xe),fe=n(e),u=i(e,"DIV",{class:!0,"data-svelte-h":!0}),U(u)!=="svelte-9ld38f"&&(u.innerHTML=xe),be=n(e),B=i(e,"P",{"data-svelte-h":!0}),U(B)!=="svelte-wva2c8"&&(B.textContent=ze),ge=n(e),c(R.$$.fragment,e),Ce=n(e),W=i(e,"P",{"data-svelte-h":!0}),U(W)!=="svelte-139ad60"&&(W.innerHTML=Pe),Je=n(e),G=i(e,"P",{"data-svelte-h":!0}),U(G)!=="svelte-hd20iz"&&(G.innerHTML=De),me=n(e),H=i(e,"P",{"data-svelte-h":!0}),U(H)!=="svelte-1qk017i"&&(H.innerHTML=qe),ue=n(e),c(N.$$.fragment,e),je=n(e),E=i(e,"P",{"data-svelte-h":!0}),U(E)!=="svelte-776wvi"&&(E.innerHTML=Ke),Te=n(e),c(Y.$$.fragment,e),Ve=n(e),O=i(e,"P",{"data-svelte-h":!0}),U(O)!=="svelte-1o0nvdm"&&(O.innerHTML=el),ke=n(e),c(L.$$.fragment,e),Qe=n(e),A=i(e,"P",{"data-svelte-h":!0}),U(A)!=="svelte-1vtbzwm"&&(A.textContent=ll),$e=n(e),c(X.$$.fragment,e),ve=n(e),c(x.$$.fragment,e),Se=n(e),z=i(e,"P",{"data-svelte-h":!0}),U(z)!=="svelte-kg4olr"&&(z.innerHTML=sl),Ie=n(e),P=i(e,"P",{"data-svelte-h":!0}),U(P)!=="svelte-1sqiojg"&&(P.textContent=tl),Fe=n(e),c(D.$$.fragment,e),_e=n(e),q=i(e,"OL",{"data-svelte-h":!0}),U(q)!=="svelte-wwks06"&&(q.innerHTML=al),Ze=n(e),c(K.$$.fragment,e),Be=n(e),le=i(e,"P",{}),il(le).forEach(s),this.h()},h(){We(o,"name","hf:doc:metadata"),We(o,"content",Cl),We(u,"class","flex justify-center")},m(e,l){yl(document.head,o),t(e,f,l),t(e,M,l),t(e,b,l),h(j,e,l),t(e,te,l),t(e,T,l),t(e,ae,l),t(e,V,l),t(e,ne,l),h(C,e,l),t(e,oe,l),h(J,e,l),t(e,pe,l),h(k,e,l),t(e,ie,l),t(e,Q,l),t(e,Me,l),h($,e,l),t(e,Ue,l),t(e,v,l),t(e,re,l),h(S,e,l),t(e,ce,l),t(e,I,l),t(e,he,l),t(e,F,l),t(e,ye,l),h(m,e,l),t(e,de,l),h(_,e,l),t(e,we,l),t(e,Z,l),t(e,fe,l),t(e,u,l),t(e,be,l),t(e,B,l),t(e,ge,l),h(R,e,l),t(e,Ce,l),t(e,W,l),t(e,Je,l),t(e,G,l),t(e,me,l),t(e,H,l),t(e,ue,l),h(N,e,l),t(e,je,l),t(e,E,l),t(e,Te,l),h(Y,e,l),t(e,Ve,l),t(e,O,l),t(e,ke,l),h(L,e,l),t(e,Qe,l),t(e,A,l),t(e,$e,l),h(X,e,l),t(e,ve,l),h(x,e,l),t(e,Se,l),t(e,z,l),t(e,Ie,l),t(e,P,l),t(e,Fe,l),h(D,e,l),t(e,_e,l),t(e,q,l),t(e,Ze,l),h(K,e,l),t(e,Be,l),t(e,le,l),Re=!0},p(e,[l]){const nl={};l&2&&(nl.$$scope={dirty:l,ctx:e}),C.$set(nl);const ol={};l&2&&(ol.$$scope={dirty:l,ctx:e}),J.$set(ol);const pl={};l&2&&(pl.$$scope={dirty:l,ctx:e}),m.$set(pl)},i(e){Re||(y(j.$$.fragment,e),y(C.$$.fragment,e),y(J.$$.fragment,e),y(k.$$.fragment,e),y($.$$.fragment,e),y(S.$$.fragment,e),y(m.$$.fragment,e),y(_.$$.fragment,e),y(R.$$.fragment,e),y(N.$$.fragment,e),y(Y.$$.fragment,e),y(L.$$.fragment,e),y(X.$$.fragment,e),y(x.$$.fragment,e),y(D.$$.fragment,e),y(K.$$.fragment,e),Re=!0)},o(e){d(j.$$.fragment,e),d(C.$$.fragment,e),d(J.$$.fragment,e),d(k.$$.fragment,e),d($.$$.fragment,e),d(S.$$.fragment,e),d(m.$$.fragment,e),d(_.$$.fragment,e),d(R.$$.fragment,e),d(N.$$.fragment,e),d(Y.$$.fragment,e),d(L.$$.fragment,e),d(X.$$.fragment,e),d(x.$$.fragment,e),d(D.$$.fragment,e),d(K.$$.fragment,e),Re=!1},d(e){e&&(s(f),s(M),s(b),s(te),s(T),s(ae),s(V),s(ne),s(oe),s(pe),s(ie),s(Q),s(Me),s(Ue),s(v),s(re),s(ce),s(I),s(he),s(F),s(ye),s(de),s(we),s(Z),s(fe),s(u),s(be),s(B),s(ge),s(Ce),s(W),s(Je),s(G),s(me),s(H),s(ue),s(je),s(E),s(Te),s(Ve),s(O),s(ke),s(Qe),s(A),s($e),s(ve),s(Se),s(z),s(Ie),s(P),s(Fe),s(_e),s(q),s(Ze),s(Be),s(le)),s(o),w(j,e),w(C,e),w(J,e),w(k,e),w($,e),w(S,e),w(m,e),w(_,e),w(R,e),w(N,e),w(Y,e),w(L,e),w(X,e),w(x,e),w(D,e),w(K,e)}}}const Cl='{"title":"웹훅 서버","local":"webhooks-server","sections":[{"title":"엔드포인트 생성","local":"create-an-endpoint","sections":[],"depth":2},{"title":"웹훅 설정하기","local":"configure-a-webhook","sections":[],"depth":2},{"title":"Space에 배포하기","local":"deploy-to-a-space","sections":[],"depth":2},{"title":"고급 사용법","local":"advanced-usage","sections":[{"title":"다중 엔드포인트","local":"multiple-endpoints","sections":[],"depth":3},{"title":"사용자 정의 서버","local":"custom-server","sections":[],"depth":3}],"depth":2}],"depth":1}';function Jl(g){return Ul(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class kl extends rl{constructor(o){super(),cl(this,o,Jl,gl,Ml,{})}}export{kl as component};
