3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでQiita APIのCLIツールをさくっと作ってみた

Posted at

概要

Qiita APIが便利でよく利用しているのですが、毎回curl やスクリプトを組むのが面倒だったので、CLIツールを作ってみました。何番煎じか数えるのはやめましたw

利用イメージ
Hyper-2.png

インストール方法

さくっと作ったので、PyPiへの登録はしていません。GitHubからソースを取得してインストールします。

> git clone https://github.com/kai-kou/qiita-py-cli.git
> cd qiita-py-cli
> pip install -r requirements.txt
> python setup.py install

# ターミナルの再起動(bash)
> exec $SHELL -l
# ターミナルの再起動(fish)
> exec fish -l

アンインストールする場合は、以下のようにします。

> python setup.py install --record files.txt
> cat files.txt | xargs rm -rf

以下の記事を参考にさせてもらいました。

setup.pyを用いてインストールしたモジュールのアンインストール方法
https://qiita.com/orion46/items/dfe476067e499cca8535

使い方

Qiitaのアクセストークンが必要となります。アクセストークンはQiitaに認証していると以下のURLから取得できます。

POST系のコマンドを利用する場合にはスコープのwrite_qiita が必要になります。情報取得だけで利用するのなら、read_qiita があれば十分です。
Qiita.png

取得できたらqiita init コマンドでアクセストークンを設定します。

# アクセストークンの設定
> qiita init
Qiitaのアクセストークンを入力してください: 

環境変数にアクセストークンを設定することもできます。

# bash
> export QIITA_PY_CLI_ACCESS_TOKEN=<Qiitaのアクセストークン>

# fish
> set -x QIITA_PY_CLI_ACCESS_TOKEN <Qiitaのアクセストークン>

アクセストークンが設定できたらコマンドを実行してみます。

> qiita get_user kai_kou

{"description": "2004-2011 フリーランス。2011-2018 株式会社グリーティングワークスでEC、バックヤード開発をプレイングマネージャーとしてAWSを超積極的に導入。サーバレス大好きっ子。Python、Ruby、TypeScript、C#とかが好み。2018/7からCloudpackにJoin。\r\n\r\nQiita記事は誰かひとりの琴線に触れたらそれでいい^^", "facebook_id": "kokaorz", "followees_count": 429, "followers_count": 79, "github_login_name": "kai-kou", "id": "kai_kou", "items_count": 79, "linkedin_id": "", "location": "Osaka, Japan", "name": "甲斐 甲", "organization": "アイレット株式会社", "permanent_id": 48549, "profile_image_url": "https://qiita-image-store.s3.amazonaws.com/0/48549/profile-images/1524132209", "twitter_screen_name": "k_aik_ou", "website_url": "https://twitter.com/k_aik_ou"}

取得結果はJSONとなりますので、jq コマンドなどで整形する前提です。

> qiita get_user kai_kou | jq

{
  "description": "2004-2011 フリーランス。2011-2018 株式会社グリーティングワークスでEC、バックヤード開発をプレイングマネージャーとしてAWSを超積極的に導入。サーバレス大好きっ子。Python、Ruby、TypeScript、C#とかが好み。2018/7からCloudpackにJoin。\r\n\r\nQiita記事は誰かひとりの琴線に触れたらそれでいい^^",
  "facebook_id": "kokaorz",
  "followees_count": 429,
  "followers_count": 79,
  "github_login_name": "kai-kou",
  "id": "kai_kou",
  "items_count": 79,
  "linkedin_id": "",
  "location": "Osaka, Japan",
  "name": "甲斐 甲",
  "organization": "アイレット株式会社",
  "permanent_id": 48549,
  "profile_image_url": "https://qiita-image-store.s3.amazonaws.com/0/48549/profile-images/1524132209",
  "twitter_screen_name": "k_aik_ou",
  "website_url": "https://twitter.com/k_aik_ou"
}

jq コマンドについては下記が参考になります。

jq コマンドを使う日常のご紹介
https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af

実装

コマンドラインパーサー

パラメータ設定はdocoptを利用しています。パーサーを自動的に作成してくれるので、お手軽です。メソッド名をいちいち書くのが面倒だったので、下記を参考にメソッドを洗い出して、必要なものだけを記載するようにしました。パラメータは、、、自力でコツコツと。。。

Python: オブジェクトのメソッド一覧を取得する
https://qiita.com/suin/items/b15f908aaf8023a8a1fc

実装の一部抜粋
def main():
    _USAGE = '''
  Qiita API CLI

  Usage:
    qiita init
    qiita create_access_token [--params=<kn> --headers=<kn>]
    qiita create_item [--params=<kn> --headers=<kn>]
    qiita create_item_comment <item_id> [--params=<kn> --headers=<kn>]
    qiita delete_access_token <token> [--params=<kn> --headers=<kn>]
    qiita delete_comment <id> [--params=<kn> --headers=<kn>]
    qiita delete_item <id> [--params=<kn> --headers=<kn>]
    qiita follow_tag <id> [--params=<kn> --headers=<kn>]
    qiita follow_user <user_id> [--params=<kn> --headers=<kn>]
    qiita get_authenticated_user [--params=<kn> --headers=<kn>]
    qiita get_authenticated_user_items [--params=<kn> --headers=<kn>]
    qiita get_comment <id> [--params=<kn> --headers=<kn>]
    qiita get_item <id> [--params=<kn> --headers=<kn>]
    qiita get_item_stock <item_id> [--params=<kn> --headers=<kn>]
    qiita get_tag <id> [--params=<kn> --headers=<kn>]
    qiita get_tag_following <id> [--params=<kn> --headers=<kn>]
    qiita get_user <id> [--params=<kn> --headers=<kn>]
    qiita get_user_following <user_id> [--params=<kn> --headers=<kn>]
    qiita list_item_comments <item_id> [--params=<kn> --headers=<kn>]
    qiita list_item_stockers <item_id> [--params=<kn> --headers=<kn>]
    qiita list_items [--params=<kn> --headers=<kn>]
    qiita list_tag_items <id> [--params=<kn> --headers=<kn>]
    qiita list_tags [--params=<kn> --headers=<kn>]
    qiita list_user_followees <user_id> [--params=<kn> --headers=<kn>]
    qiita list_user_followers <user_id> [--params=<kn> --headers=<kn>]
    qiita list_user_following_tags <user_id> [--params=<kn> --headers=<kn>]
    qiita list_user_items <user_id> [--params=<kn> --headers=<kn>]
    qiita list_user_stocks <user_id> [--params=<kn> --headers=<kn>]
    qiita list_users [--params=<kn> --headers=<kn>]
    qiita stock_item <item_id> [--params=<kn> --headers=<kn>]
    qiita unfollow_tag <id> [--params=<kn> --headers=<kn>]
    qiita unfollow_user <user_id> [--params=<kn> --headers=<kn>]
    qiita unstock_item <item_id> [--params=<kn> --headers=<kn>]
    qiita update_comment <id> [--params=<kn> --headers=<kn>]
    qiita update_item <id> [--params=<kn> --headers=<kn>]

  Options:
    --help             ヘルプを表示
    --params=<kn>      params [default: None]
    --headers=<kn>     headers [default: None]
  '''
    all_params = docopt(_USAGE)

docopt
http://docopt.org/

Pythonのdocopt使い方メモ
https://qiita.com/ymdymd/items/651245d80964393b12c5

PythonでCLIツールを作成するのにdocoptでパラメータのパーサー作成を自動化する
https://qiita.com/kai_kou/items/5ff0958264c56ecf0a17

Qiita APIへのアクセス

下記で紹介されているラッパーを利用させてもらいました。一部APIの実装が足りていなかったので、フォークしました。

Qiita API v2のPythonラッパー実装した
https://qiita.com/petitviolet/items/deda7b66852635264508

kai-kou/qiita_py: Python Wrapper for Qiita API v2
https://github.com/kai-kou/qiita_py

基本的にはラッパーで実装されているメソッドをパラメータとして引き渡し実行しているだけです。お手軽!

実装の一部抜粋
    command = [k for k, v in all_params.items() if v == True]
    params = [
        v for k, v in all_params.items()
        if re.match(r'\<.*\>', k) and v is not None]
    options = [
        json.loads(v) for k, v in all_params.items()
        if re.match(r'^\-', k) and v != 'None']
    params.extend(options)

    ()
    client = QiitaClient(access_token=access_token)
    res = getattr(client, command[0])(*params)

getattr を利用して、メソッドを動的に呼んでいます。下記が詳しく参考になりました。

pythonで動的にクラスとメソッドをCallする
https://yuji0602.hatenablog.jp/entry/2018/03/21/225700

まとめ

CLIツールを初めて作ってみましたが、便利なライブラリが充実しているので、とても簡単に実装することができました。

さくっと実装したので、テストも書いてない状態なので、テストを書いたらPyPiに登録してみたいと思います^^

参考

docopt
http://docopt.org/

Pythonのdocopt使い方メモ
https://qiita.com/ymdymd/items/651245d80964393b12c5

Qiita API v2のPythonラッパー実装した
https://qiita.com/petitviolet/items/deda7b66852635264508

Pythonにおけるリフレクション
https://qiita.com/icoxfog417/items/bf04966d4e9706eb9e04

pythonで動的にクラスとメソッドをCallする
https://yuji0602.hatenablog.jp/entry/2018/03/21/225700

Python: オブジェクトのメソッド一覧を取得する
https://qiita.com/suin/items/b15f908aaf8023a8a1fc

Python: PyPI にないパッケージを依存パッケージにするには
https://blog.amedama.jp/entry/2016/02/18/221555

Pythonで関数の引数にリスト、タプル、辞書を展開して渡す
https://note.nkmk.me/python-argument-expand/

Pythonでリストとタプルを相互に変換するlist(), tuple()
https://note.nkmk.me/python-list-tuple-convert/

Pythonで対応する値に基づいて辞書型のキーをフィルターしたい
https://teratail.com/questions/3731

Python Prompt Toolkitで対話的な選択コマンドを作る
https://vaaaaaanquish.hatenablog.com/entry/2017/12/25/183927

Pythonでyamlファイルを設定ファイルとして使う
http://www.bokupy.com/detail/74

pythonでホームディレクトリの取得
https://qiita.com/sotetsuk/items/d7b32b12f94a341c79a5

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?