pythonでslackのmessage buttons
TL;DL
こんなのがあったから, 試すがてらPythonで再実装してみた.
SSLとかはLet’s Encryptとかでよしなにやってほしい。
1点注意としては、現在Firefoxからslack appの作成をしようとするとどのチームでslackアプリを作るか?という選択肢が選べない。Chromeとかだと上手くいく。
背景とかモチベーション
- 現在の会社で所属しているチームには定型的なオペレーションがある
- 手順は確立されているがもっと効率化, 自動化したい
- が、最終的な対応の実施可否は人間が判断したい
- 実行しますか?の問いにyes, noで回答させて欲しい
- が、最終的な対応の実施可否は人間が判断したい
という背景があった上で、
- 通知を受け取った人間がCLIで1コマンド叩く形の自動化は嫌
- Jenkinsとかも違うなぁと思った
- 通知と対処をシームレスに実行できれば嬉しい
そんなこんなでインタラクティブにシステムとやりとりできるslack message buttonsがいい感じに自動化のUIになってくれるのではないか?と思って試した。
個人的には以下の流れができたら最高だなと思っていた。
(一連の流れは全てslackのメッセージとしてlog化) なにかしらの出来事 -> slackへの通知 (yes, noのbuttonの送信) -> yesを押したらスクリプト等の実行 -> noなら何もしないで終了
成果物
所感
- slack の message buttonはSSL必須
- 試すだけなら, 単純に手間もしくは制約が多くなるだけ
- Herokuで制約をとるか
- Let’s Encryptで手間をかけるか
- 試すだけなら, 単純に手間もしくは制約が多くなるだけ
- とはいえ、たんなるコミュニケーションツールとして、message button を用意するのは面倒だなぁと思った.
- slackのUIでオペレーションをするのは厳しい
message button
をレスポンスするアプリケーションのセキュリティ的な問題
問題点
どこまでslackを信用するかの問題。
message button appの作りとしては、以下の2つの点でアプリケーションのセキュリティを担保しようと考えている
- httpsでの通信
- slackしか知らない, slack app用の
Verification Token
を使う- アプリケーション側で
Verification Token
をチェックする
- アプリケーション側で
コレだけだと、slackから送信されてくるリクエストによく似たリクエストが送られてきたら対処のしようが無い.(特に、Verification Tokenが漏れたとかのケースを考えると…)
個人的には上記に加え, 以下の対策が取れれば良いのだけどなぁと思った。
- slackのリクエストもとIPもしくはIP帯が公開されていること
- slack appを動かすサーバーに対して、送信元IPでFWをかけられるようにする
送信元IPで制限がかけられればVerificationTokenが漏れましたとかなっても大丈夫なはず。
しかし、結局これでも、 万が一slackのサーバーが乗っ取られて「slackのサーバーからいろいろrequestを投げてみました(´・◡・`) 」 みたいな自体になると対処のしようが無い。
message button でアンケートが取りたいとかの、「ちょっとしたコミュニケーションの延長線上の事をやりたい」程度なら万が一message button用のアプリに不正なリクエストがあっても問題ないはずだが、「インタラクティブに実行したいオペレーション」を実行するアプリケーションに不正なリクエストがあった時のことを考えると結構厳しいはず.
なので問題点としては、以下となると思っている.
どこまでslackを信用するか
ただし、slackの問題というより、コミュニケーションツールをコミュニケーションから大幅に外れた用途で使おうと検討した自分が原因なので、slackには全く落ち度が無いと思っている.
まとめ
- slackでサービスのオペレーションはリスクがあるのを認識できた
- 実際に手を動かしてみたから, そこら辺に気づけたと思っている
- 個人的考えてた用途としては厳しい
DIとリポジトリパターンは何が嬉しかったのか?がよくわからなくなった。
まだ色々考えている途中
上記のページからリポジトリパターンの良さを抜粋すると以下の様な事が挙げられている
テストがしやすくなる
DBエンジンの変更に対応しやすくなる
データ操作のロジックが1箇所にまとまり、管理しやすくなる
そうだよねと思いつつ、Laravel系でリポジトリパターンに言及している別のページも見て回った.
結果、気がついた事が一つある。基本的に返り値を言及していない。
当たり前過ぎて言及されていない前提の話しなのかもしれないが。
例えば、SQLite様に書いたリポジトリがsqliteのコネクションを返し、Redis様にかいたリポジトリがredisのコネクションを返したら、リポジトリインターフェースを要求しているコードはそのDBエンジンに寄ってコードを書き換える必要が出てくる. それでは本来のリポジトリパターンの意味が薄いと思った。
DBエンジンをすげ替えられるようにpythonで書いてみた
とりあえず自分で書いてみたら答えが出るかもと思って、RedisとSQLiteと単なるモックコードを切り替えられるようにした。
以下のページの183行目で生成するクラスを変更したら使われるDBが変わるようになっている
実行結果は基本的に同じようになっているはず (だが途中でめんどくなってredisあたりのconfiguとか端折ってる)
書いてみた結論として
- たしかにテストはし易いはず
- DI自体は例えばコントローラーのテストの際にmodelのモックが気軽に差し込めるのは良いと思う
- リポジトリパターンでなくても良いのでは?という気持ち
- リポジトリに持たせる実装がもう少し厚い場合考えが変わるかもしれない
- 現状リポジトリにはどの位の責務で実装を持たせたら良いのかがわかってない
- が、DBを操作する系のメソッドが長くなるとその実装自体がテストできなくなるので…
- リポジトリパターンってなんだ?
- アダプタ
ということで、本日のブログ 「DIとリポジトリパターンは何が嬉しかったのか?がよくわからなくなった。」 になる。
追加の参考
上記のリンクを見るに、自分の実装ではリポジトリパターンになっていなかった。
リポジトリ内で実装をすげ替えるより、リポジトリに対して更にクライテリアをDIするほうが責務としてはきれいに別れて良さそう.
だけど根本的な疑問として、そこまでしてRDBMSとNoSQLとの互換性を保ちたいか?と聞かれると微妙なのは変わらず.
vSphereでterraformする時のポイント
VMを立てるだけならばvagrantでも良い気がするし、色々設定するならAnsibleで事足りている.
が、仮想基盤に対してリソースを用意するための適切なツールを利用する意味で、terraformを利用してみる
入門自体は以下
公式ドキュメントのvSpherプロバイダページ
ポイント
provider
の箇所にはallow_unverified_ssl = true
記述すること- vSpher providerのドキュメントをパクっていくと分かる
- vCenterあるあるの証明書の話し
resource "vsphere_virtual_machine"
にはskip_customization = true
を記述すること- いつまでたっても
apply
が終了しない- 何やら、
network_interface
の項目に, labelしか記述しないと正常に終了しないらしい?- customizationがいじれないのに、これ以上何を記述したら良いのか (´・_・`)
- 問題のissueは以下 github.com
- とりあえずぶち切っても大丈夫そう
- 何やら、
所感
- ドキュメントを見る感じ、出来ること
- Ansibleとの比較
- HCL
- www.terraform.io
- 使い込んでないけどYAMLより良いと思う
- なんとなくレベルの話し
haskell で gnuplotを利用する + 利用したときの個人的な詰まりどころ
gnuplot: 2D and 3D plots using gnuplot を利用してみた
だいたい以下のページの感じで出来る.
ただし今回はもうチョット踏み込んだことをやってみる。
用意
gnuplot等の用意は上記のページを見て欲しい。
haskellのライブラリとしてのgnuplotはstack
で準備できるので、プロジェクト.cabal
にgnuplotを追記したら良い
library hs-source-dirs: src exposed-modules: Lib build-depends: base >= 4.7 && < 5 , gnuplot default-language: Haskell2010
で、stack build
したら怒られるはずなので、 stack solver
とか stack build --modify-stack-yml
とかを叩いてやれば良い
棒グラフのサンプル
module Lib ( someFunc ) where import Graphics.Gnuplot.Simple someFunc :: IO () someFunc = do plotPathStyle [(Title "Frequency"), (XTicks (Just ["('hoge' 0, 'huga' 1, 'piyo' 2)"]))] (defaultStyle{plotType = Boxes }) [(0::Int,0), (1,1), (2,2)]
stack ghci > someFunc
以上で実行可能
スタイルはデフォルトのまま
gnuplotで出来ることとしてはもうちょいいい感じに出来るはずだけど、 もう少しきれいにやるなら Graphics.Gnuplot.Advances
を使う必要がある。
詰まりどころ1
まず注意しなければならないのが、 おそらく GHCiからでないと利用できない様子. ドキュメントにGHCiかHugsから使えるよって書いてある.
少なくとも自分の環境ではコンパイルが上手く行った後のバイナリを動作させても、gnuplotが起動することは無かった。
ただしstackの環境であれば、 stack ghci
を実行すると src/Lib.hs
のモジュールを読み込む設定が最初から書かれているので、 コードを書いてghciから実行させる形で妥協したら良いと思う。
詰まりどころ2
ghciから実行させるのは良いが、gnuplot自体はおそらく非同期でコードが実行される。 非同期で実行されるから、間違ったコードで死んでるのか、処理中なのかわかりづらい。
具体的には遅延評価される重めのlistをgnuplotに突っ込もうとすると、動いているのかどうかよくわからない問題が発生する. (自分は1~2日気づかなかった)
そんなときはtopコマンドを見れば良い。
Processes: 332 total, 3 running, 329 sleeping, 1548 threads 00:29:13 Load Avg: 1.97, 2.12, 2.08 CPU usage: 13.71% user, 1.45% sys, 84.83% idle SharedLibs: 174M resident, 43M data, 48M linkedit. MemRegions: 67643 total, 5202M resident, 175M private, 3489M shared. PhysMem: 16G used (2002M wired), 22M unused. VM: 1930G vsize, 627M framework vsize, 0(0) swapins, 0(0) swapouts. Networks: packets: 256919/208M in, 222563/26M out. Disks: 870239/13G read, 162387/6235M written. PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS IDLEW POWER 12713 ghc 99.8 00:17.90 5/1 0 14 1778M 0B 0B 12700 12700 running *0[1] 0.00000 0.00000 501 525572 1375 70 34 150746+ 3997 15304+ 59 316 99.8
ghcがCPU利用率100%で張り付いているって言うことは、裏で頑張って処理しているんだな。ってことが分かる
入門自然言語処理 第1章
2017年度上期目標達成プロジェクトの第1週目
方針
- 本はpython2だがpython3で通す
- 本を読んでpython3対応するのがめんどくさくなったら以下を読む
python2 -> python3 のマイグレーション点
nltk.download()
がさっくり動かない- 止まった所はちまちまダウンロードする
- それでも1こだけダウンロードできなかったやつがある
- 一旦無視 こまったら考える
- nltk.text.Text の generateメソッドが使えない
- ntlk3の問題で、それより古いか新しいかで使えるらしい
- これも困ったら考える
- python3の
dict_keys
でindexへのアクセスができなくなってる - nltk.probability.FreqDist でplotした時の縦軸が%ではなく単語の総数となっている
- 英語サイトを見たら、%表示では無くなってるのでまぁよしとする
- (が,正直, plotした時の値は%軸の方が良い気がする)
- 英語サイトを見たら、%表示では無くなってるのでまぁよしとする
- bigrams関数が無い
from nltk.util import *
で使えるようになる- generatorなのでforで回す
雑なメモ
- 語義曖昧性解消
- 文章内の単語と単語をくっつけて、文章の意味を正しく解釈する
- 代名詞解析
- 文章の流れから代名詞(theyとか)を正しく推測する
- 言語出力の生成
- 問に対する答えを作る?
- 機械翻訳
- 音声対話システム
- bot的なもの
- 知っている?という問いに対してyes no ではなく, 推論して解答を返す
- 含意関係
- 1つの文章から, 別の文章の真偽をチェックする
雑な感想
- たしか大学の教科書って聞いてた
- pythonの基本的な説明が多い
- 個人的には不要
- 初心者にはありがたいかもしれないが、python2なので改定が必要そう
- python3でも意外と動いたり動かなかったり
- 言語処理100本ノック
- 1日1問くらいで、現在30問目くらい
- 100本ノックの際はnltkがアレばだいたいokでは?って思えた
- 便利
- bigrams
- collocations
- 便利
- nltk.chat.chatbots()が面白い
- Iesha (teen anime junky)
- が中身はちょっとしょぼい?
- 各章ごとに演習問題がついている
- 2章からは取り組もうとおもう
- 正直pythonの基礎文法をやるのは怠いので
- 2章からは取り組もうとおもう
haskellで空文字列を指定するときの方法
タイトルのまんま。
結論
“\NUL"を使うと良い
発覚までの流れ
pcre-heavy: A regexp library on top of pcre-light you can actually use.
上記のライブラリを使って正規表現でマッチさせて置換しようと思った時の話
具体的な実行したいこと
現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更
から '
を取り除き
[[スターリング・ポンド|UKポンド]] (£)
を UKポンド (£)
にしたいとき
抽象的にすると
'
を取り除く[
を取り除く]
を取り除く[[$some_word|
を取り除く
バグるパターン
gsub [re|('+|\[\[.*\||\[+|\]+)|] (""::String) x
これだと中途半端に動くのがタチの悪いところ
うまくいくパターン
gsub [re|('+|\[\[.*\||\[+|\]+)|] ("\NUL"::String) x
空文字列を指定するときは \NUL
を使う必要がある模様. ただしHaskell的には常識的な話なのかもしれない.
どこかのwebサイトで, \NUL
を指定しているのを見つけて試したらうまくいったのだが, どこのサイトなのかがわからなくなってしまったのが残念.
2017年度上期の目標
目標
- 作者: Steven Bird,Ewan Klein,Edward Loper,萩原正人,中山敬広,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/11/11
- メディア: 大型本
- 購入: 20人 クリック: 639回
- この商品を含むブログ (44件) を見る
半年かけて、上記の本を通そうと思う.
出来れば土日のどちらかで1.5hくらいを使って取り組みたい.
目標設定の基準は、現在自分がプライベートで取り組んでいること(直接業務とは関わりのないこと)で選んだ.
思ったこと
wikipediaを眺めると,大学の1単位は45時間の学習が目安らしい. とはいえ、実際には22.5時間で2単位でてる.
仕事をしつつとは言え, 業務とは関係のない話題を毎週1.5時間の学習が無理なのか?と問われると… 実際は可能な気もする.
最近の出来事として
write code everyday に感化されて, ハードルを低く*1, 1日1問プログラミングで問題を解くことをしてみている.
現在解いている問題は以下.
まだ初めて3weekしか立ってないので、この活動はもう少し続いたらまとめるつもり
*1:wirte code everyday の記事を読む限り, 毎日コードを書きましょうと言う意図より, 毎日ソフトウェアを開発しよう!って感じが読み取れた. 個人的に毎日ソフトウェアを開発し続けるのは様々な面で難しいと思ってる.