rcmdnk's blog

Web API: The Good Parts

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

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

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

Sponsored Links

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 nameHomepage URLApplication descriptionAuthorization callback URLを記入する様になります。

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

今回はAplication nameOctopressHomeepage URLhttps://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: 1ce216d8eecec746d441
github_client_secret: f09421379d28914341790ff89c871ccc3fecbba5

を加えます。

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

Sponsored Links
Sponsored Links

« GNU screen + Vimでのターミナル運用(主に領域設定について)