rcmdnk's blog

Web API: The Good Parts

このOctopressのブログの中でGitHubのGistを取ってくるプラグインを使っていますが、 その中でまずGitHubのAPIを使ってGistの情報を取ってきています。

所が最近そのプラグイン周りでエラーが起きてるな、と思ったら APIの使用制限回数にひっかかっていたみたいです。

その問題の回避のためにやった設定について。

Gist情報API

https://api.github.com/gists/<Gist ID>

と言ったURLにアクセスするとそのGist IDのGistの情報をJSON形式で返してくれます。

https://gist.github.com/rcmdnk/cd17909e73b5df45ca9356a2b1f264ab

と言ったGistなら

https://api.github.com/gists/cd17909e73b5df45ca9356a2b1f264ab

になります。

使用回数制限

ところが通用APIへのアクセスは同一IPからは一時間に60回までの制限があります。

GitHub API v3 GitHub Developer Guide

制限を超えると

{"message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)", "documentation_url": "https://developer.github.com/v3/#rate-limiting"}

と言った内容のJSONを返してきます。

ここに出てるURLが上のDeveloper Guideなわけですが、 Authenticatedなリクエストなら5000 requests/hourまで使える様になる、とのこと。

Client ID/Client Secretの取得

上のGuideに行くとClient IdとClient Secretを使ってAuthenticatedなリクエストをすれば 良いことが分かります。

これらは

New OAuth Application

で新たなアプリケーション登録をすることで取得することが出来ます。

行くとApplication name、Homepage URL、 Application description、 Authorization callback URLを記入する様になります。

Application description 以外必須ですが、 Authorization callback URL を記入しない場合 Homeepage URLが自動的に適用されます。

今回はAplication nameにOctopress、 Homeepage URLにhttps://rcmdnk.comを入れて作成。

そうするとClient IDとClient Secretが取得できます。

これらを使って

https://api.github.com/gists/<Gist ID>?client_id=<client_id>&client_secret=<client_secret>

の様にしてアクセスすると一時間に5000回までアクセス出来る様になります。

Octopressのgist_tag.rb

Octopress(2.X)にはgist_tag.rbというプラグインが入っています。

octopress/gist_tag.rb at master · imathis/octopress

これを以下のような感じにClient IDとかを使える様にします。

以下の様な感じの変更です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
diff --git a/plugins/gist_tag.rb b/plugins/gist_tag.rb
index 94afb846..ca7750e6 100644
--- a/plugins/gist_tag.rb
+++ b/plugins/gist_tag.rb
@@ -22,6 +22,15 @@ module Jekyll
     end

     def render(context)
+      config = context.registers[:site].config
+      client_id = config["github_client_id"] || ""
+      client_secret = config["github_client_secret"] || ""
+      if client_id != "" and client_secret != ""
+        client = "?client_id=#{client_id}&client_secret=#{client_secret}"
+      else
+        client = ""
+      end
+
       if parts = @text.match(/([a-zA-Z\d]*) (.*)/)
         gist, file = parts[1].strip, parts[2].strip
       else
@@ -31,7 +40,7 @@ module Jekyll
         ""
       else
         script_url = script_url_for gist, file
-        code       = get_cached_gist(gist, file) || get_gist_from_web(gist, file)
+        code       = get_cached_gist(gist, file) || get_gist_from_web(gist, file, client)
         html_output_for script_url, code
       end
     end
@@ -50,9 +59,12 @@ module Jekyll
       url
     end

-    def get_gist_url_for(gist, file)
-      data = JSON.parse(get_web_content("https://api.github.com/gists/#{gist}").body)
+    def get_gist_url_for(gist, file, client="")
+      data = JSON.parse(get_web_content("https://api.github.com/gists/#{gist}#{client}").body)
       if file == ""
+        if not data.key?("files")
+          raise RuntimeError, "Failed to get gist file info: #{data}"
+        end
         file = data["files"].keys[0]
       end
       data["files"][file]["raw_url"]
@@ -79,8 +91,8 @@ module Jekyll
       File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache"
     end

-    def get_gist_from_web(gist, file)
-      gist_url = get_gist_url_for(gist, file)
+    def get_gist_from_web(gist, file, client="")
+      gist_url = get_gist_url_for(gist, file, client)
       data     = get_web_content(gist_url)

       locations = Array.newllkk

ちょっと元々のgist_tag.rbとは違いますが、 実際に使ってるものは以下になります。

octogray/gist_tag.rb at master · rcmdnk/octogray

さらに_config.ymlに**

_config.yml
1
2
github_client_id: <CLIENT_ID>
github_client_secret: <CLIENT_SECRET>

を加えます。

これでClient IDとClient Secretを使ったアクセスが出来るようになって 制限回数を多くすることができます。

Sponsored Links
Sponsored Links

« GNU screen + Vimでのターミナル運用(主に領域設定について) Cygwin(Bash/Zsh)からPowerShellスクリプトを直接実行するbashrc/zshrc設定 »

}