8つの質問で、Hadoop業界の現状を知る


Webサービス系の隆盛があったのかどうかはよく知らないが、Hadoopのリリースが騒がれたのが7年前ぐらいだろうか。Hadoop業界の人材動向が、今どうなってるかって?

大方の予想より凄惨ですよ。

それが分かる方法がある。Hadoop技術者に技術力を問う8つの質問によってだ。Hadoop業界のエンジニアの平均レベルを知りたくって、いろんな会社さんのHadoop開発者(経験者)向けに以下のような8つの質問をしてみたいと思ってるけど、やったことはない。 対象者としては、Hadoop経験3から4年の現役バリバリのはずのHadoopエンジニアだ。

その8つの質問というのはこんな問題だ。

Hadoop技術者に技術力を問う8の質問

  1. 投機的実行のメリットを一言で表して下さい。(筆記解答)
  2. ネームノードのRPCアドレスを取得するコマンドは何ですか?(筆記解答)
  3. 標準jarファイルでベンチマークを取る方法を説明してください。(筆記解答)
  4. 複数の出力を生成するためのクラスはどれですか?(選択解答。複数回答可)
    1. MultipleOutputs
    2. MultipleOutputFormat
    3. MultiOutputFormat
    4. MOutputs
  5. MapReduceを書いているのに、思ったほど実行時間が短くなってくれません。CPUコア数は足りているようです。原因として何が考えられますか?(筆記解答)
  6. MapReduceでMap処理だけを使用するのはNGですか?そうであればその理由を説明してください。(筆記解答)
  7. Yarnでノード一覧を取得するためのコマンドは何ですか?(筆記解答)
  8. APIでカウンタをカウンター名の指定により取得するメソッドは何ですか?(筆記解答)


過去に実施した平均点
この8問について、僕が出会ったエンジニアに解答してもらった平均正解数は、なんと8点満点中8点(予想)である。





この辺まで書いて力尽きた。

おまけ

Go Conference 2013 springというイベントが開催されます。凄惨なGo業界の現状を打破したいそうなので手伝いましょう。直前でキャンセルが出るはずなので、とりあえず並んでみて下さい。

Go Conference 2013 spring - connpass

Disclaimer

煽ったのは id:ymotongpoo です。私は乗せられて書いただけです。

PyFes 2013.3 参加メモ #pyfes

午前: Riak ハンズオン

Riak ハンズオンに参加したと思っていたらいつの間にか Riak ハンズオンを手伝う側に回っていたでござる

教訓

  • インターネットがまともに使えない、かつ全員がMac という特殊な環境だと AirDrop を使って必要なファイルをばらまくという技が使える。かなり限定的な条件ではあるが、便利
  • ハンズオンで構築からやらせるのはリスク高過ぎと再確認

ハンズオンについては別途ブログを書くかもしれない

Go ( @ymotongpoo )

http://www.slideshare.net/ymotongpoo/20130316-go

  • Go 言語の紹介
  • 内容はいつも説明を聞いているのでほぼ知っていた。初めて説明聞いた人には面白い内容のはず
  • プレゼンうまくなっててびっくり

Mock と patch ( @torufurukawa )

http://www.slideshare.net/torufurukawa/mock-and-patch

テストが難しいメソッド

例: urlopen の結果は不確定なのに、その結果に依存するメソッド

  • 戻り値が不確定
    • 乱数
    • 時刻
  • セットアップがだるい

だから、テスト対象の外側を入出力として扱う

mock モジュール
  • 3.2 以前は PyPI
  • 3.3 標準ライブラリ unittest.mock
mock の 使い方
  • 依存先オブジェクトを入れ替える
    • 例: urlopen を mock に入れ替える
    • with patch で入れ替える

with patch('urllib.request.urlopen') as m:
...
... from urllib.request.urlopen ...
これが m になる

  • @patch で入れ替える
    • with はインデントが深くなるのであまり好きじゃない

@patch('urllib.request.urlopen')

  • call_count で呼び出し回数を確認

assert m.call_count == 1

  • call_args で引数を確認
  • 依存先の挙動を定義する
    • m.return_value = 999
      • 返り値が 999 になる。
    • m.return_value.meth.return_value = 1
      • m().meth()
    • 複雑な戻り値は side_effect

def f(x, y): ...
m.side_effect = f

例外も side_effect に指定可能



MS Surface でゲームを作った話 ( @tokoroten )

巷で話題の Surface ではない本物の Surface
静電容量式はオワコン

APIC# なので pygame からアクセスする場合はソケット通信で入力メソッド部分を置き換えれば既存のゲームを移植可能

Introduction of Leap Motion (@hagino3000 )

http://www.slideshare.net/hagino_3000/introduction-of-leap-motion

手の認識に特化した小型モーションキャプチャデバイス

机の上にちょこんと置いて手をかざして使うことを想定している

  • センサー: 赤外線センサー
  • 接続: USBインタフェース
  • 高分解能(0.01mm), 速い(> 60 FPS), 安い
  • Pre Order
    • < $90
    • 5/13 以降順次発送
  • 開発者登録
    • 一個無料で送ってくれる
    • 製品版と一部異なる
    • 起動に開発者IDとパスワードが必要
    • 作ったアプリの勝手配布はNG

Arduino + Python 勉強会の紹介 ( @nonNoise )

といっても基本技術は既に固まっているのであとはこれをどう遊ぶかという話

Tinkerer ( @r_rudi )

Sphinx を利用したブログ作成ツール
tinker コマンドを使う
更新のたびに全ファイル生成し直し

  • drone.io
    • travis ci のような自動テストツール
    • bitbucket 対応
  • S3
    • 転送量課金される
  • Dropbox
    • アクセス量で金額は増えないが、独自ドメインが使えない

webpay ( @keikubo )

1時間で使えるクレカ決済

USでは決済市場が白熱している

日本の決済システムは問題がいっぱい
だから日本で開発者向けの決済システムを作った。それが webpay


ライブマインドマッピング ( @sawonya )

@3_and_planet による身の上話をマインドマップ
2人目の人は名前がわからなかった cobit の話
@wozozo による身の上話をマインドマップ

WebMachine ( @voluntas )

https://gist.github.com/voluntas/f99838001efced196fc0

  • Webmachine
    • Basho 製 REST ツールキット
    • Erlang 専用?
      • 「考え方」なのでどんな言語でもOK

Blender ( @lab1092 )

  • オープンソース 3DCG ソフトウェア
  • Open Movie Project
    • Blender の開発をしながら映画を作るプロジェクト
  • Python 3.3 が使える
  • Rapid Release
  • Git 対応

インターネットの経済学 ( @JHarrison )

Webサービスってどれほどの価値があるのか?

Fabric ( @drillbits )

https://speakerdeck.com/drillbits/fabric-python-developers-festa-2013-dot-03-number-pyfes

  • 環境はたくさん作らなきゃいけない
    • 開発、本番、ステージング、ステージング2、ステージング3、...
  • pip install fab
  • オプションでユーザ名、ホスト、SSH鍵などを指定可能
  • env にオプションを指定することも可能

Opsworks & Chef ( @tk0miya )

http://www.slideshare.net/TakeshiKomiya/ops-works-chef

  • why chef
    • 冪等性
      • 手続き型ツール(Capistrano, Fabric)は順序が重要(差分更新)
    • community cookbooks
      • 大抵のツール向けの設定が集約
      • 再利用の精神
      • 理想はほとんど書かない
  • chef の種類
    • chef-server
      • 大規模用、クライアントサーバ型
    • chef-solo
      • 小規模運用、手動実行
      • 20台くらいまでなら chef-solo で十分
    • ホスティング
      • 有料プラン
chef-solo
  • vagrant
  • librarian
    • cookbook 管理ツール
    • yum や apt みたいなもん
    • 依存関係解決 Java 入れたりとか
    • Chef 使うなら最初に覚えたい
    • 類似ツール: Berkshelf
      • どっち使ってもいい
  • attributes を書く
    • json 形式で書いていく
  • 実行する
    • コマンド一発
tips

capistrano 経由で実行すると便利

  • chef 情報が少ない
    • id:naoya による書籍
    • Ryuzee さん、セカコミさんによるブログ
  • チームへの布教が大変
  • コミュニティクックブック
    • Ubuntu が多く、CentOS に対応していないものも多い
    • attributes 化されていない設定項目がある
    • 似たような cookbook がたくさんある
    • パッチを投げても無反応
OpsWorks
  • AWS のアプリ管理ツール
    • 環境構築
    • アプリのデプロイ
    • インスタンスの起動/終了の管理
      • スケーリング
      • スケジューリング
  • まだバグが残ってる
    • This is oops works

団長 (団長)

メモはとったけど公開しない

moriyoshi さん

AnyPack Builder
素晴らしい

最も無価値なものを探す

駅を降り、夜道を歩いて帰る途中、ふと思いつき「今目に映るもののうち、最も無価値なものはなんだろう」と考えてみました。
こんな視点で周囲を見渡すと、普段は全く価値を感じない様々なものが、意外にも価値があることに気づきます。
マンホールや排水口は、雨が降ったときの水はけに不可欠ですし、工事現場の金網は侵入防止の機能だけでなく不意にぶつかってしまったときの衝撃吸収に役立ちます。
「最も価値あるものを探す」という視点よりも、「最も無価値なものを探す」という視点の方がかえって多くの価値に気づくことができます。


これはよく考えれば自明の話です。
人間は自分本位な生き物なので、「最も価値ある」というのは無意識のうちに「(自分にとって)最も価値ある」という言葉に置き換えられます。

一方、最も無価値なものを探す場合、世の中の大半のものは自分にとって無価値なので、自分本位の価値判断だと比較ができません。
例えば、マンホールに大きな価値を見いだしている人は相当少ないはずです。
「より」無価値なものを探そうとすると、必然的に自分以外の価値基準で比較しなければならなくなります。

私にとっては無価値でも、ご近所さんに必要なものはたくさんあります。
住民にとって無価値でも、工事現場の作業員にとって重要なものもたくさんあります。
そんな視点でものを見渡すと、無価値なものって意外と見つからないものです。


案外、自分自身が今目に映る何よりも一番無価値なものなのかもしれません。

hadoopプロジェクトの規模(2013/01/25版)

@ に手伝ってもらいながら、hadoop プロジェクトのコードの行数をカウントしました。

サブプロジェクト 行数
common 198,303
hdfs 234,070
mapreduce 221,630
yarn 158,067
hadoop-tools 59,713
maven-plugins 522
合計 872,305

というわけで合計87万行でした。4つのサブプロジェクト(common, hdfs, mapreduce, yarn) に分かれているとはいえ、それにしても大きいです。

おまけ: 他のプロジェクトの行数

プロジェクト名 行数
HBase 633,922
Hive 410,005

Hive は id:oza_x86 さんにカウントしてもらいました。thx!

さらにおまけ: コードの行数計算 via cocoatomo


リンク: https://gist.github.com/4623120

コミュニティに非協力的な人への向きあい方

あけましておめでとうございます。


一昨年は大晦日の夜は一人で過ごしながら hadoop のパッチを書いていましたが、昨年末は大晦日はおろか新年の元旦含めて年末年始ぶっ通しで仕事に追われてました。
そんなわけでコミケもネットで眺めてひっそり楽しむ程度だったわけですが、一つ非常に印象に残ったツイートがありました。



真偽のほどは分かりませんが、こうしたポリシーはコミュニティを長生きさせる上で非常に重要です。
コミュニティが小さいうちは、お互いをきちんと理解している仲間だけで行動しているのでコミュニケーションの問題はほとんどありません。
しかし、ある程度大きくなると、コミュニティに「非協力的な」人がでてきます。
例えば上記のツイートに書いてあるような、コミュニティのポリシーに反した言動を行う人達です。
こうした人を放置しておくと、単にその人の周りの迷惑になるだけでなく、他の(特に新参の)コミュニティ参加者に誤った考えを植えつけたり、コミュニティに対する外部からの見方も変わるなど、コミュニティ全体に影響を及ぼすことになります。
よってこのような人達に対して何らかのアクションをとらなければいけないわけですが、このような「悪い人」達に対して叱責し、ひどい場合は排除するというアクションは割と広く受け入れられているのではないかと思います。(一応念のため書いておきますが、コミケの話ではなく、一般的なコミュニティの話です)
しかし、上記のツイートのような考えこそが、コミュニティの健全さを保つ最高の考え方です。

実はほとんど同じ話が、コミュニティ形成・運営について書かれた書籍「アート・オブ・コミュニティ」に書かれています。

対立を避けるためのtips

  • コミュニティの中の人の行動に影響を与える要因について理解しましょう。
  • 対立を引き起こす人がいたら、彼らがどれくらい成長できそうか考えます。もしあなたが彼らの成長を信じて待つことができるのであれば、中傷している人にも同じように信じるよう働きかけましょう。
  • 毒性を持つ人を特定してよく観察し、彼らの与える損害が広がらないように注意します。次に、彼らが関心を持っていることを特定し、議論の場を持ちます。コミュニケーションの問題を1 つずつ取り除いて、彼らの心配を落ち着かせます。

(アート・オブ・コミュニティ、p240)


これらの話はコミュニティ内部における対立にフォーカスしていますが、コミュニティ外部との対立についても全く同じ話が適用できます。

なぜこのようなことを書いておこうと思ったかというと、下記リンク先の青空文庫に対する批判とそれに対する反論などを読んだからです。


「青空文庫」はアブナイ? - Togetterまとめ


私個人の意見としては、批判に対して反論されている方とほとんど同じ意見です。
青空文庫の提案には、青空文庫の理念が書かれています。

電子出版という新しい手立てを友として、私たちは〈青空の本〉を作ろうと思います。
青空の本を集めた、〈青空文庫〉を育てようと考えています。

青空の本は、読む人にお金や資格を求めません。
いつも空にいて、そこであなたの視線を待っています。
誰も拒まない、穏やかでそれでいて豊かな本の数々を、私たちは青空文庫に集めたいと思うのです。

先人たちが積み上げてきたたくさんの作品のうち、著作権の保護期間を過ぎたものは、自由に複製を作れます。
私たち自身が本にして、断りなく配れます。
一定の年限を過ぎた作品は、心の糧として分かち合えるのです。


現在青空文庫で行われている活動はこの理念になんら反していませんし、この理念を理解していれば最初の批判のようなものが出てくるというのは的外れのように感じます。

だからといって批判者に対し批判で返していいのかとも思います。

  • 批判された方は本当にこの理念を理解していたのか?
  • 理解していないのであれば、それをまず説明するという選択肢はないのか?
  • そもそも、もっと上記ページがわかりやすいところにあればこのような批判は出なかったのでは?(ちなみに上記ページは、初めての人が読むページである青空文庫早わかりのかなり下の方にあります)


などなど、考えるべき点は色々あるんじゃないのかと思うのです。

もちろん私は青空文庫コミュニティには一読者として以上の貢献はしておらず、関係者から見れば上記の指摘もまた見当外れな妄言かもしれませんが、その場合はご容赦ください。
この記事の主旨は青空文庫コミュニティの運営の話ではなくコミュニティ運営全般の話です。


だから私が最も関心のある hadoop コミュニティでも、こうした話は常々気をつけなければいけないことだと思っています。
批判が出ることはコミュニティを育てるチャンスなのです。
健全なコミュニティを育てるためにも、批判はありがたく受け止めていきたいと思います。

最後に、「アート・オブ・コミュニティ 9章 対立への対処」で引用されているナポレオンの言葉を再引用させていただきます。

あなたが恐れるべきは、賛同しない人ではなく、賛同しないで、なおかつ臆病さからあなたに知らせようとしない人である。

―― ナポレオン・ボナパルト


アート・オブ・コミュニティ ―「貢献したい気持ち」を繋げて成果を導くには (THEORY/IN/PRACTICE)

アート・オブ・コミュニティ ―「貢献したい気持ち」を繋げて成果を導くには (THEORY/IN/PRACTICE)

Hadoopに関する雑感 (Hadoop アドベントカレンダー2012 XX日目)

最近はなるべく技術的な話しか書かないようにしていたのですが、たまには個人的な思考を書いてみることにします。
クリスマスだし、ブログ初めてから8周年でもあるわけですし。


Hadoop は、大量のデータをリーズナブルに計算処理できるようにしたいという課題から生まれました。
つまりキーとなる課題として、

  • データが大量である
  • リーズナブルである
  • 計算処理ができる

というものがあります。
後ろ2つは話が早い。低コストで計算処理を行いたいというのはほとんどのIT関係者が抱くニーズでしょう。
しかし、「データが大量である」という課題が厄介です。
まず第一に、「そんな大量のデータがどこにあるのか?」という問題があります。
たとえば1日1TBのデータを生成したとしても年間365TBです。ようするに 0.3PB。ビッグデータの代名詞として言われる「ペタバイトオーダー」には程遠いです。
1日1TBって、要するに1時間あたり50GB近くデータを生成するわけです。


仮にデータは用意できたとしましょう。しかしもっと根本的な問題として、「大量のデータを処理するとどんな課題が解決できるのか?」という問題があります。
実際にデータを抱えている人にとっては容易な問題です。データ量が膨大になり、既存のDWHやRDBでは処理できない量になってきた。大量のデータが処理できれば解析がもっと楽になる、というものです。
しかしこの質問にはさらなる質問があります。
「データ解析すると何がうれしいの?」という話です。
この問題の方が数段深刻です。
このあたりはshowyouさんの記事でも言及されていますが、ほとんどのデータ解析担当者はExcel使ってます。たった5万円のCognos使った方がいいんじゃね?という意見にも耳をかさず、ひたすらExcel縛りプレイで解析し続けてます。
(たまにExcelバカにする人いますが、Excelはデータ解析の世界におけるデファクトスタンダードです。バカにしてはいけません。Excel方眼紙を憎んでExcelを憎まず)


さて「縛りプレイ」、要するにわざわざそんな不便なことをしている、という表現をしました。さてこの表現は適切でしょうか?
実際のところ、多くの人にとってExcelで足りてしまっています。
大量のデータの解析どころか、データ解析の世界でさえほとんどの人は課題に思っていません。
はっきり言うと、多くの人にとってHadoopは要らない存在なのです。


去年おかちまちさんが書いた記事から1年経過しましたが、その後このビッグデータ業界はどうなったか。
確かにユーザは増えています。
新しいクラスタを稼働させて今までは不可能だったデータ処理を行うことができるようになった人もいますし、既存のクラスタを大きくしてさらに大量のデータを処理することができるようになった人もいます。
しかし、ほとんどの人が「Hadoop」についての妙な誤解や、特に妙な期待を持ったまま動いていないというのが現状でしょう。
要するにほとんど何も変わってません。


で、じゃあその問題をどうやって解決するのよ、という話。
「課題ないんだからそのまま黙って死ねよ」という話は置いておきます。あと本当に私が食っていけなくなって死にます。
課題課題、とさっきから書いてるわけですが、新しいテクノロジーを使うのは本当に課題があるときだけなのか?
私は最近違うんじゃないかと思い始めました。
よく「日本でロボットが発達したのは鉄腕アトムドラえもん、ガンダムのおかげである」などと言われますが、真偽の程は別にして、憧れがテクノロジーに触れる原動力になるというのも往々にしてあるはずです。
じゃあその憧れの存在がデータ解析の世界にあるか?というと、実はこれもほとんどない。
SFの世界では宇宙船やテレポート装置、携帯式の何にでも使えるコンピュータなどが登場してきました。
このうち最後のアイデアは今ではスマートフォンと呼ばれ、現実世界の道具となっています。
こういう子供でも喜ぶような夢物語が、データ解析の世界にないというのが実は一番深刻なんじゃないかと思うのです。

「ログ解析してリコメンデーション」や「機械学習による高度な分類・フィルタリング」などなど、知識としてのデータ解析のパワーは多くの人が知っています。
もっと古典的な「統計・確率」も立派なデータ解析の技術です。これらのパワーを疑う人はいないでしょう。
じゃあ、おとぎ話の世界としてのデータ解析はあるか、というと、多分ほとんどない。
(もし知っている方がいましたら教えてください)

Hadoop は多分当分の間なくなりません。
しばらくの間、冬の時代がくるかもしれませんが、分散処理の需要そのものはなくなることはありません。
なぜならデータは増える一方だし、データの解析は人間の意思決定において必須だからです。
今は課題が少なくても、いずれ現実の課題に直面する人が増えてくるでしょう。
その前に私は食いっぱぐれるかもしれませんが、そのときは次の私がきっとうまくやってくれるでしょう。


でも、その課題を解決したいというモチベーションの最後の原動力は、やっぱり夢だと思うのです。
ファンタジーの世界の魔法使いのように、SFの世界の科学文明のように、人の願望を実現するようなスーパーヒーローが現れるかどうかで、今後の運命が決まるのではないかと、私はそう思うのです。
夢がなければ、ただの地味な仕事で終わってしまいます。
夢と言っても、今世の中で言われている「Hadoopを使えばこう変わる」なんて絵本のお伽話以下の世界です。何ら具体性がありません。


幸い、希望はあります。
2012年秋から放送されているアニメ「サイコパス」は、データ解析に関するエピソードがあちこちに出てきます。
サイトへのアクセス傾向からの真犯人特定、監視カメラ記録から特定人物だけの抽出、使用単語の違いから同一人物かどうかを判定など、データ解析をふんだんに使っていて非常に楽しいです。
そもそもサイコパスのテーマ自体が「人の主観を挟まない、データ解析の結果のみで人の善悪を判定することが正しいのかどうか」というものみたいだし、データ解析に携わる人にとっては見る価値のあるアニメと思います。

このサイコパスの世界観は決して明るいものではありませんが、データの解析によってこれだけのことが実現できるという可能性を示してくれています。
こういう作品がもっと世の中に出てくるとうれしいですね。


寺田寅彦の又又聞きですが、アインシュタインは教育についてこんなことを言っていたそうです。少し長い引用ですが読んでみてください。

例えば数学の教え方でも、もっと実用的興味のあるように、もっとじかに握つかまれるように、もっと眼に見えるようにやるべきのを、そうしないから失敗しがちである。子供の頭に考え浮べ得られる事を授けないでその代りに六むつかしい「定義」などをあてがう。具体的から抽象的に移る道を明けてやらないで、いきなり純粋な抽象的観念の理解を強いるのは無理である。それよりもこうすればうまく行ける。先ず一番の基礎的な事柄は教場でやらないで戸外で授ける方がいい。例えばある牧場の面積を測る事、他所よそのと比較する事などを示す。寺塔を指してその高さ、その影の長さ、太陽の高度に注意を促す。こうすれば、言葉と白墨はくぼくの線とによって、大きさや角度や三角函数などの概念を注ぎ込むよりも遥かに早く確実に、おまけに面白くこれらの数学的関係を呑み込ませる事が出来る。一体こういう学問の実際の起原はそういう実用問題であったではないか。例えばタレースは始めて金字塔の高さを測るために、塔の影の終点の辺へ小さな棒を一本立てた。それで子供にステッキを持たせて遊戯のような実験をやらせれば、よくよく子供の頭が釘付けフェルナーゲルトでない限り、問題はひとりでに解けて行く。塔に攀よじ上らないでその高さを測り得たという事は子供心に嬉しかろう。その喜びの中には相似三角形に関する測量的認識の歓喜が籠っている。

この言葉はそのまま現在のHadoopやビッグデータの世界にも当てはまると思うのです。
机上の空論ばかり先行して、実際が伴わない。
私のようなベンダーの人間が常々気をつけなければいけないことで、また現状については反省しなければいけないことでもあります。

この2年半ほどHadoopを触ってきましたけれど、未だ私のレベルはこの程度です。
使い道にせよ、使い方にせよ、自分が知らなければいけないこと、人に伝えなければいけないことは多々あります。


ほとんどHadoop関係のない話になりましたが、たまには思うがままを書いてみることにしました。

sphinx拡張開発メモ ( #sphinxjp アドベントカレンダー 13.1日目)


前回の記事では私が作成した sphinx 拡張、sphinxcontrib-recentpages の紹介をしました。

この記事では sphinx 拡張の開発をしたときに気づいたことなどのメモを紹介します。

私は sphinx 拡張の開発は初心者ですので、間違いがあるかもしれません。間違いを発見した場合はご連絡いただけると助かります。

チュートリアル


まずはチュートリアルをやること。
http://sphinx-users.jp/doc11/ext/tutorial.html

基本

まず def setup(app): という関数を作る。

ノード

  • app.add_node(<ノード名>) で登録。
  • このノードは新しいクラスとして、docutils.nodes.<ノード> クラスを必要なだけ継承する。
class recentpages(nodes.General, nodes.Element):
    pass
  • add_nodes() に追加で引数を渡すことができる。
    • html = () と指定すると、html のビルド時にそのノードを訪れる(あるいは立ち去る)際の挙動を決めることができる。

ディレクティブ

  • app.add_directive(<ディレクティブ名>, <対応クラス>) でディレクティブを登録。
  • ディレクティブクラスは sphinx.util.compat.Directive を継承する必要がある。
class RecentpagesDirective(Directive):
  • ディレクティブ作成には run(self) というメソッドを作る必要がある。
    • この関数はディレクトリが見つかるたびに呼ばれる。
    • 返り値はノードのリストになる。
  • ディレクティブに引数を持たせたい場合は以下のように設定する。
    has_content = True
    option_spec = {
        'num': int
    }

  • こうしておけば、ユーザは以下のような形でオプション引数を渡せる。

.. recentpages::
:num: 3

  • run() メソッド内で以下のようにして取得できる。
    • 以下の例ではデフォルトを -1 にしている。
        num = self.options.get('num', -1)
  • ノードは dict 形式なので、情報を渡したい場合は dict に値を追加するのと同じ感覚で大丈夫。
        res = recentpages('')
        res['num'] = num
Directive の中身
  • directive.state
    • ディレクティブについての状態を扱うオブジェクト。
  • directive.state_machine
    • ディレクティブについての状態を扱うオブジェクト。
  • directive.state.document
    • そのディレクティブが属するドキュメントについてのオブジェクト。
  • directive.state.document.current_source
    • ドキュメントへのフルパス。
  • directive.state.document.settings.env
    • Sphinx の環境オブジェクトはここからアクセス可能。
  • directive.state.document.settings.env.srcdir
    • ドキュメントのルートディレクトリ。


例えば、そのノードが属するページの pagename は以下のように生成可能。

pagename = current_source.replace(srcdir, '').lstrip('/').rpartition('.')[0]

環境情報

  • 現在の環境情報は directive.state.document.settings.env あるいは application.builder.env に入っている。
  • env() の使い方は sphinx.environment のソースコードを参照のこと。

ビジター関数

  • def <メソッド名>(self, node): で定義する。
  • node は現在のノード。ここで node['num'] とすれば、先ほどディレクティブクラス内で投入したデータを取り出せる。
  • env は self.builder.env で取り出せる。

conf.py

  • conf.py の設定は app.builder.config.<コンフィグ名> で取り出すことができる。
  • 例えば以下の例では、 recentpages_sidebar という設定の値を取り出すことが可能。
app.builder.config.recentpages_sidebar

tips

  • あるディレクティブが存在するページを常にビルドしたい場合は run() 内で self.state.document.settings.env.note_reread() を呼ぶことで可能。
  • Sphinx プロジェクトのルートパスは env.srcdir で取得可能。
  • builder は app.builder で取り出せる。
  • env は app.builder.env で取り出せる。
  • Sphinx プロジェクト内で発見された全てのソースファイルの一覧は env.found_docs で取得可能。
  • builder.get_relative_uri(pagename, docname) で、あるページから別のページへの相対 URI を生成できる。
  • あるドキュメントへのフルパスは env.doc2path(docname) で取り出せる。
  • ビルド時の warning は builder.warn(<メッセージ>) で出力可能。
  • あるドキュメント名の表示時のタイトルは env.titles[docname] で取得可能。