Hugging Face Spacesで、plumberで作成したWeb APIをホストする方法

:::note warn
Hugging Faceを利用し始めて間もないので、情報に誤りがあったり冗長なやり方で紹介しているかもしれませんが、温かい目で読んでいただけると幸いです。修正のご指摘大歓迎です！
:::

Hugging Face Spacesで、plumberで作成したWeb APIをホストする方法を備忘録として書き記します。尚、GitHubとHugging Faceのアカウントがすでにあることを前提としています。

GitHubのレポジトリの中身をご覧になりたい方は、サンプルのレポジトリを作成しているので、以下のリンクからアクセスできます。

https://github.com/Myxogastria0808/hugging-face-plumber-mytutorial


## GitHubのレポジトリを作成し、cloneする

## いくつかのファイルを作成する

以下のファイル群をcloneしたレポジトリに追加してください。

```plumber.R
library(plumber)

#* @filter cors
cors <- function(req, res) {
  res$setHeader("Access-Control-Allow-Origin", "*")
  if (req$REQUEST_METHOD == "OPTIONS") {
    res$setHeader("Access-Control-Allow-Methods", "GET")
    res$setHeader(
      "Access-Control-Allow-Headers",
      req$HTTP_ACCESS_CONTROL_REQUEST_HEADERS
    )
    res$status <- 200
    return(list())
  } else {
    plumber::forward()
  }
}

#* Root Endpoint
#* @get /
function() {
  return("Hello")
}

```

```pr.R
library(plumber)

path <- paste0(getwd(), "/", "plumber.R")
plumber::plumb(path)$run(host = "0.0.0.0", port = 7860)
```

以下、Dockerfileの内容

```Dockerfile
FROM rstudio/plumber:latest

COPY . .

EXPOSE 7860

CMD ["Rscript", "pr.R"]

```

以下のyamlの記述は、公式サイトで書かれていたyaml( [公式サイトのこのページに書かれていたyamlです。](https://huggingface.co/docs/hub/spaces-github-actions) )を少しだけ変更して作成しています。このGitHub Actionの設定を書くことで、GitHubのmain branchのpushがあったとき、または手動でGitHub Actionsを動かしたときにGitHubのレポジトリの内容をHugging Faceに自動でpushするようになっています。

```.github/workflows/hugging-face.yaml
name: Sync to Hugging Face hub
on:
  push:
    branches: [main]
  # to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  sync-to-hub:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
          lfs: true
      - name: Push to hub
        env:
          HF_USERNAME: ${{ secrets.HF_USERNAME }}
          HF_SPACE_NAME: ${{ secrets.HF_SPACE_NAME }}
          HF_TOKEN: ${{ secrets.HF_TOKEN }}
        run: git push https://$HF_USERNAME:$HF_TOKEN@huggingface.co/spaces/$HF_USERNAME/$HF_SPACE_NAME main

```

以下のようなディレクトリ構成になっていればOKです。

```
.
├─ .git
│  └──(以下略)
├── .github
│  └── workflows
│     └── hugging-face.yaml
├── Dockerfile
├── plumber.R
└── pr.R
```

## Hagging Faceで新しいSpaceを作成する

Select the Space SDKはDockerを選択してください。

## README.mdと.gitattributesを作成する

作成したSpaceにある`README.md`の中身をコピーして、ローカルのGitHubレポジトリに作成したREADME.mdにコピーします。その際、`---`で行の先頭と最後を囲む必要があります。
以下に、一例を見せます。

```README.md
---
title: Hugging Face Plumber Mytutorial
emoji: 💻
colorFrom: pink
colorTo: purple
sdk: docker
pinned: false
license: mit
---

```

作成したSpaceにある`README.md`の中身をコピーして、ローカルのGitHubレポジトリに作成した`.gitattributes`にコピーします。

以下のようなディレクトリ構成になっていればOKです。

```
.
├─ .git
│  └──(以下略)
├── .github
│  └── workflows
│     └── hugging-face.yaml
├── Dockerfile
├── .gitattributes
├── plumber.R
├── pr.R
└── README.md
```

## GitHubの該当のレポジトリにSecretsを追加する

以下の3つをSecretsとして追加してください。`HF_TOKEN`はHagging FaceのAccess Tokensで作成したTokenです。

- HF_USERNAME
- HF_SPACE_NAME
- HF_TOKEN

## GitHubにpushする前準備

以下の２つのコマンドを実行してください。尚、HF_USERNAMEは、Hugging Faceのユーザー名、HF_SPACE_NAMEは、該当のSpaceの名前に置き換えてから実行してください。

```sh
git remote add space https://huggingface.co/spaces/HF_USERNAME/SPACE_NAME
git push --force space main
```

## GitHubにpushする

上記のすべての操作が完了したら、GitHubの該当のレポジトリにpushしましょう。GitHub Actionsでエラーが発生していないかとHugging Faceの作成したSpaceで問題なく動作していることを確認できたら、成功です！

#### お疲れ様でした！

## 参考サイト

https://huggingface.co/docs/hub/spaces-github-actions