koboriakira.com

今週のアウトプット

今週はWeek42でなくWeek43だということに気づき、修正。

  • PACKERSFUNは今週も更新を継続できた。
  • 英文から情報を取得するスピードもすこし上がってきた。なんとなく「ここが要点だ」というのが見えるようになったため。
  • 同じくDEV.TOの記事も読んで紹介・翻訳しようかと考えた
  • こどもの動画編集がやっと進んだ
  • Airで処理するには限界がありそうなので、週単位ぐらいでレンダリングすることに
  • つまり毎週ちょこちょこやっておけば、そんなに大変でないはず。あとは毎週できるか、ってところだけ
  • このあと今週をやる予定
  • 開発はTypeScriptに少し慣れた
  • 具体的には関数コンポーネントの実装とテスト
  • テストはテキストの確認のみ。次週は動作のテストができるようにする
  • すこしインプットが増えたので、CRAを使わずに自分でプロジェクトを整備するほうも再開したい
  • TodoistのCLIや新日本プロレスの検索アプリは公開前。ドキュメントなど公開するための準備をしたいなと思っているうちに1週間が過ぎてしまった
  • そのほか習慣リストの作成をはじめた
  • Todoリストの「繰り返し」ではなく、あるイベントに対して「発火」して「パイプライン」で実行されるタスクをイメージ
  • たとえば「こどもが朝寝したら」、「爪を確認する」、そして「爪が伸びていたら」、「爪を切る」
  • 「そんなことまで書かないといけないの?」となりそうだが、意外に侮れないと思う

今週は、15分間スプリントとAtomic Habitsを知って、それぞれを試した1週間だった。

自己啓発全体にはそれほど興味が湧かないものの、「タスク管理」や「習慣」については結構考えているほうだと思う。そのなかで把握してきたのは次の通り。ちょっとしたビジネス書なら書けそうな勢い(とくにレッテルがないので書かないけど)。

  • 行動には「意識の行動」と「無意識の行動」がある
  • 心理学や精神分析の《意識/無意識》ではなく、シンプルに「やろうとハッキリ思っているかどうか」程度の違い
  • さらに行動には「計画された行動」と「触発された行動」がある
  • 「12:00にA社とMTG」、「今日はかならず書類を提出する」などは「計画された行動」
  • 「朝起きたら水を飲む」、「電車に乗ったら携帯を見る(見てしまう)」などは「触発された行動」
  • これら2つをもとに、行動を4パターンに分ける

| | 意識 | 無意識 ||:---:|:---:|:---:|| 計画 | 予定
12:00にA社とMTG
今日はかならず書類を提出する | 身体
7:00頃には目が覚める
休日は昼頃まで寝る || 触発 | 傾向
朝起きたら水を飲む
高価なものを買うときには1日空ける | 反射
電車に乗ったら携帯を見る
家に帰ってきたらテレビをつける|- たいていの行動は「無意識の行動」かつ「触発された行動」=「反射」である- 「意識の行動」は、その粒度と達成可能性が反比例の関係にある

  • 粒度が大きければ達成されないことが多い
  • 例)今日は2時間ジムに通う
  • 粒度が小さければ達成されることが多い
  • 例)帰りがけにボールペンを買う
  • たいていの「触発された行動」は、次の「触発された行動」を規定する
  • 例)「甘いものを食べる」と、「しょっぱいものを食べる」
  • 「予定」として習慣づけにチャレンジするのは悪手
  • 例)「毎朝7:00にランニングを30分する」は習慣になりづらい
  • むしろ習慣は「傾向」の連鎖として定義して、「反射」になるまで繰り返すようチャレンジするのが正しい
  • 例)「朝起きたら水を飲む」、「水を飲んだらウェアに着替える」、「ウェアに着替えたら外に出る」、「外に出たらすこし歩く」

2020年10月18日、日曜日。

Bが生まれてから半年。この世界に”入場”してからもう6ヶ月が経ったと思うと、よくある感想ながら、とても驚く。

最初はすこしでも扱いを間違えたら生存できないんじゃないかと思うぐらい小さくて、自分たちの布団に載せると「無人島に取り残された」みたいな画になって、喋りかけても反応がなくて、ラトルを振っても気にしなくて、50mlのミルクを飲むのに10分かかって、夜中に何度も泣いていたのが、いまはLサイズのオムツを履いて、200mlのミルクを飲み干し、離乳食も食べはじめ、目を合わせれば喜び、おもちゃを掴んで振り、うつ伏せから顔を上げて周囲を確かめたり、前に進もうとして誤って後退したりしている。

2度目のよくある感想ながら、こどもの成長や変化は大人の想像するものとは根本的に違うのだと感じた。これからも成長・変化のタイミングがたくさんあるといいなと思うし、大人側がそれを制限してしまわないように気をつけないと、とあらためて自戒。


今日もTodoistCLIの開発に集中。基本機能はほぼできた。と思ったところで、GoによるCLI実装があったのを見つけてしまった。まあそりゃあるよね。

まと新日本プロレスの検索システムをすこし改修。もう公開しようかな。不具合は再発しなかったのでいったん放っている。

2020年10月19日、月曜日

朝早く起きてパッカーズの試合を見る。が、早起きしなければよかったと思うぐらいに完敗。

調子の悪いときはつづくもので、Bを連れてマイナンバーカードを取得しにいったが、ちょうど午前の部は終わってしまったと返答。帰ってる途中に雨が振りだした。


ボーッとしながら過ごしていたらもう夜に。

Qiitaで下記の記事を読み、githubのリポジトリを検索してみようかと思った。

独学してエンジニア職についた初級者が中級者になるためにプライベートで実践している学び方 - Qiita

ためしにstars:1000..10000 language:Python license:mit created:>2020-01-01で検索してみると、色々とヒット。starsが1000って結構すごいと思いつつも、意外にテスト無しのプロダクトばかりだった。

そのうち読んでみたい&機能追加&テスト実装できそうなリポジトリをためしにforkする。


TodoistCLIはテストを実装。かなり大変だったけれど、おかげでロギングの注入を覚えた。

2020年10月20日、火曜日

「15分スプリント」を個人に適用しようと思い、Todoistを使って実験。

ただTodoistにマニュアルで時間を記入するのは面倒だったので、yaml経由でTodoistに好きなプロジェクトを入れられるようなプログラムを書いた。


NFLのWeek6のハイライトを見て、PACKERSFUNの記事を執筆。

そのほかはあまり進まなかった。インフルエンザの予防接種をしたのでずっと血の気が引いたからかもしれない。

2020年10月21日、水曜日

Bが朝寝している隙に、15分スプリントに則って作業。とはいえ最初のTodoは「計画」で、これが一番大変。どんな「整理」も大変なのは「何を捨てるか」である。

そのうち起きてきたので一緒に居間に降りて、ペンギンの起き上がりこぼしで遊ぶ。Bは目的の場所に行きたい意欲は見せるものの、身体がまだ上手く扱えないみたいで、後ろに戻ったり回転してしまったりしている。前に進めるようになっただけで泣くかもしれない。


やっと動画編集を再開した。

Final Cut Proが重くて悩んでいたのだがプロキシを使うことで編集作業は軽くできることを知った。あとメディアをとりあえず放り込むと作業時間が余計にかかりそうなので先に使うメディアを決めることにする。


配偶者がBを連れてピクニックに行った。美容院へ4ヶ月ぶり(!)に行って、帰宅後はPACKERSFUNにプレイ分析を書く。

カウントアプリも作ろうと思ったが、ダラダラしているうちに手つかず。すこしだけ実装して、これをテストする方法を調べていたら時間が来てしまった。なんとなく使い方は見えてきたけど、実際にやりはじめたら大きくつまづく予感がしている。

2020年10月22日、木曜日

昨日は早めに寝室に行ったが眠れず、睡眠不足のまま起床。Audibleで『ジェームズ・クリアー式 複利で伸びる1つの習慣』を聞いてたせいかも。

眠気はずっとあったが、とりあえず15分スプリントの準備をして、textlintを導入し、直近の資産を記録し、Bの朝寝を遂行。

寝ている間に動画作成を進める。とりあえず4月分はOK。明日からは現在と5月以降を並行して進めていこうかなと考えている。


昼寝して、PACKERSFUNの記事を書く。

夕方からは配偶者が飲みに出かけたので、風呂と寝かしつけは一人で。19:30頃に寝てくれたが、今日はもう自分の時間をつくる気力が出ない。

とはいえTypeScriptの記事を読んでいたらやりたくなってきたので、ちょっとだけやる。

2020年10月23日、金曜日

昨日も21時には寝室に向かったが眠れずに25時ぐらいになってしまった。ヒートテックを着たまま寝ていたことに気づき、とりあえず脱いだらその少しあと眠れた。


眠れない間『複利で伸びる1つの習慣』のことを考えていたが、つまるところAtomic Habitsはプログラミングでいう「パイプライン」なのだと感じた。

シェル操作では、ひとつひとつのコマンドは小さく、これをつなげて任意の操作を行うことができる。習慣もそのようにして組み立てるべきだ、というのが著者の主張(のひとつ)である。

パイプラインにはいくつかの種類があるが、おそらく習慣に使われるパイプライン&&だろう。つまり”習慣A”が成功したら”習慣B”をする、というのが習慣パイプラインの基本になる。

ここで重要なのは、“習慣A”に失敗すると”習慣B”は実行対象にならないことである。

「5時に起きて、英語の学習を15分して、栄養のある朝食を自炊して食べる」みたいな習慣づけを目標にしたとき、「5時に起きる」が失敗すれば、「英語の学習をする」も「朝食を自炊する」も実行対象にすらならない。最初の行動につまづいてしまったからだ。

言い換えれば習慣づけるためには、粒度の細かい習慣をパイプラインでつなぎ、確実に最後までコマンドを流しきれるように設計するのが重要だということになる。

もうすこしアナロジーを続ければ、習慣とは「テスト可能」なものでもある。短いステップかつ成否の判定しやすい(確実に緑のシグナルが出ないといけない)習慣を連鎖させること。これが習慣づけの基礎になると学んだ。


昼食後、外に出る時間をもらってファミレスへ。眠気がとれなかったが気合を入れ直してデイリープランをつくり、スケジュールに沿って試合のプレビューを更新する。最近やっと自分の書いている内容が、ほかメディアの論調と合うようになってきた。同じような見方ができている感じがして嬉しい。

帰宅後Bとすこし遊んでお風呂。あがったら配偶者が寝かしつけてくれるので、その間にTypeScriptでReact開発を進める。小さなジャイアントステップとして、関数の型定義がすこしわかった。

勢いそのままにJestとEnzymeを使ったテストも体験。適当にイジってたら成功してくれた。シンプルなコンポーネントであれば何とかなりそう。次はもうすこしだけ複雑なコンポーネントのテストを実験してみよう。


Week41

2020/10/17

今週のアウトプット

  • 申込みに必要な資料を準備する
  • B関連のモノを片付ける
  • 新日本プロレスの検索システム
  • 翻訳ツールの機能追加
    • 読んだ文章の単語を集計
  • TodoistのCLIを作成
    • プロジェクト一覧
    • 対話モードでGTD
    • インボックスの整理
  • Bのマイナンバーカードを取得する
  • Bの動画をまとめる
  • ISUCONの試験をやってみる
  • Reactの学習メモをつくる

新日本プロレスの検索システムが完成。シングル戦をタイムツリーで並べることを思いつき、Material-UIですぐに実装できた。普通におもしろいサイトになったと思う。不具合を修正して公開予定。

またTodoistのCLIがなかったので、腰を据えて作ってみることに。最低限の機能ができたら公開してしまおうかと思う。プルリクが飛んできたら嬉しいな。


Bの動画をまとめようと思っていながら手をつけていないので、来週は必ずやろうと思う。マイナンバーカードも取れる状態になったので来週天気の良い日に連れて行く。

ISUCONは取り組めそうなことがわかったけれど、実際にやってみるところまではモチベーションが上がらなかった。来週中に取り組まなければ「いつかやる」に移してしまおう。

ReactはuseEffectの使い方をすこし覚えた。TypeScriptをやりたいので、次につくるアプリで採用して勉強しながら実装しようと思う。

2020年10月10日から13日

日記を誤って消して保存してしまった。

覚えている範囲で書くと、新日本プロレスの検索システムをほぼ完成させた。Whooshを利用した経緯をメモっていたのだが、Qiitaにまとめなおそうと思う。

2020年10月14日、水曜日

いつもどおりの朝。試しに書いてみると、まずゴミ捨てをして新しいゴミ袋を用意。そのあとBにミルクをあげながら自分もバターコーヒーを飲む。洗濯機をかける。汚れた食器が残ってれば食洗機をかける。居間の整理をして、掃除機をかける。余裕があればトイレ掃除も。書いてみると単純なことだけど毎日やるのは大変。

タイタンズ対ビルズがやっていたので(思い出した。昨日のセインツ対チャージャーズはすごかった。やっぱりセインツが勝つのかい、って思った)、それを見ながら今週の振り返りを書く。

---ISUCONについて取り組むことができるかどうかを調べてみた。 公式がISUCONの過去問にチャレンジするためのシンプルな環境構築 : ISUCON公式Blogという記事をあげてくれているので、これを参考に取り組もうと思う。実践は明日から。

2020年10月15日、木曜日

夜になってから書いている。バーガーキングにて。さっきまで一日中Bといっしょにいて、2011年頃の内藤哲也を見たりした。

あとはTodoistのCLIを作成したくなって試してみる。タスクの完了/削除はできたものの、プロジェクトの移動が上手くいかない。モジュールの不具合ではと疑っている。

---PACKERSFUNに、Week6のプレビューを投稿。

2020年10月16日、金曜日

今日もBと一緒に過ごす。

最近はベビーカーに乗っても寝ないことが増えてきた。今日は遠くの公園まで一緒にいって、木の下で過ごした。本当はそこで寝かす予定だったが寝ず。

ただ帰宅中に爆睡しだしたので、すこし自分の時間にさせてもらう。


翻訳ツールについて機能追加をいくつか。 読みたい文章にふくまれている単語をカウントして、そのうち覚えていないものを抽出できるようにした。

またCSSを少し勉強。display:flexmarigin-left: autoを使ってブロックを左右に分けたりできるようになった。


PACKERSFUNを更新した時点で、そろそろ体力が尽きてきた。 そういえばオスプレイがヒールターンしたことを書いておかないと。久々にプロレス見ながら大声が出た瞬間でした。

2020年10月17日、土曜日

ひさびさに寝坊して9時半に起きてしまった。早朝に起きだしていたBはすでに朝寝を済ましており、目がルンルンしていた。かわいい。

居間に降ろして、一緒に過ごす。NGSL判定のプログラムの簡単な不具合を直しつつ、朝の家事を終える。寒くなってきたのでユニクロでキルトのカバーオールを注文した。


週次レビューを終えたあと、TodoistCLIの開発を進める。自分が悪いのかモジュールが悪いのかわからなかったが、HTTP経由でAPIを呼び出すと任意の処理ができたので、そっちを使うことにした。

結局夜までやっていて、なんとか基本機能は開発。日付指定でタスク、プロジェクトを指定できるようにしたら、ベータ版を公開してしまおうかな。


Week40

2020/10/10

今週のアウトプット

  • Cloud Run + FastAPI ( + Firestore)のテンプレートを作成する
  • みずほ銀行の株価予想プログラム
  • Reactまわりを勉強する -> 実施中
  • 追加
  • 新日本プロレスワールドの検索システムを開発しはじめる

週の前半は旅行に出かけていたので、今週はかるく開発したぐらい。

ReactはReact Hooksを勉強できたことがよかった。useStateuseEffectの基礎を覚えたのが、たぶんもう少し勉強が必要そう。

そしてTypeScriptを完全に忘れていたことに驚いた。CRAをTypeScriptでやるとエラーしか出ないので、ちょっと基礎を復習しないといけない。

2020年10月3日、土曜日

久々に遅い起床。ちょうどBが寝ていたので、一人でコーヒーを淹れていたらBの泣き声。育児マンガみたいな展開だった。

朝のうちに『脱力タイムズ』を見ながら週次レビュー。今週はReactをガッツリやろうと思った。とくにReact HooksとCSSフレームワーク(Material-UI)を勉強しないと、作りたいものは作れなさそう。またCloud Run+FastAPIのテンプレートを作ってみたいなと思った。


昼は新設される保育園の説明会に出席して(予想通り自分以外は女性だった。だから何か意味がある訳ではないけど)、帰宅後はBと遊びながらReact Hooksのことをイメージする(ドキュメントを読む余裕がなかった)。

夜になってすこし時間ができたので、ReduxからContext API with Hooksへを参考にさせてもらいつつ、実験。


パッカーズ関連のニュースをザックリ取得してPACKERSFUNに出したいなと思い、RSSフィードとGoogle翻訳を使って、今日の記事一覧をMarkdownとして書き出せるようにした。

2020年10月4日、日曜日

生活リズムを戻して起床。

Bと遊んだり、うんちを拭いたりしつつ、昨日つくったパッカーズ関連ニュースを読む。RSSフィーダーで取得することもできたのだけれど、自分でつくったものは、

  • Slack通知できる
  • タイトル、サマリをGoogle翻訳してくれる

というメリットがあり、そのおかげで「あ、これは面白そう」という記事にアクセスしやすくなった。

ためしにこれを利用して30分で「今日のパッカーズ」をPACKERSFUNに投稿。


翻訳ツールがある程度完成。そのなかでReact Hooksを理解した。「stateを使うならクラスコンポーネント」と思っていたけれど、関数コンポーネントにstateを”Hook”できるわけね、と理解した。

またCORSについてもなんとなく対応できた。single requestとpreflight requestの違いを知らないといけないのが初心者には結構つらそう。

2020年10月5日、月曜日

起床してBにミルクを飲ませたり、一緒にヒップホップを聴いたりしたあと(遅めのビートに絞って一緒に踊った)、今週のサンデーナイトフットボールを視聴。49ers対イーグルス。イーグルスが勝つとは思ってなかった。49ersはQBガロポロの不在がそのまま影響してる。

翻訳ツールはDEV.TOに対応させる。ReactやVS Codeに関する記事を読んだ

昼から配偶者に代わってもらい箱根へ。

以前から予定していた通り、2日間の休暇をもらって一人で旅行。どこかに出歩く気にもならないので、サウナ併設の旅館に泊まってのんびりする計画。

東海道本線でビールを飲みつつ(最近糖質制限の期間に入ったのでビールは久しぶり。こんなにエビスって美味しかったっけ?)、NFLの他試合のハイライトを見たりしながら移動。

ふと思い立ってiriとeillに関するnoteを書きすすめた。もうちょっと書けたら公開してしまおう。


夕方前に旅館に着。温泉とサウナに入って、しばらくボーっとする。18時に夕食。部屋に戻ってからは買っておいたアルコール類をデタラメに飲んで就寝。

2020年10月6日、火曜日

久しぶりに一人で目覚める。昨晩はたっぷり飲んで、そしてたっぷり寝た。気分がいいのでインスタントコーヒーに久しぶりに砂糖を入れて飲む。コンビニのインスタントコーヒーは、冷めると焼き芋みたいな味と香りがすることを思い出した。

PACKERSFUNの更新をしたあと、チーフス対ペイトリオッツ戦を見ながらKAGOYAに置いていたアプリケーションのCloud Run移行作業をする。ChromeDriverを使っているものがあり移行が大変だったのだが、すこしずつ学習しながらなんとか完了しそうなところまで。

パッカーズ対ファルコンズの時間になったので切り替えて応援。今回は余裕だった。次週はバイウィークなのでちょっとさみしい。


試合が終わるともう13時を過ぎていたので外に出て、ビールを飲みながら(外で歩きながら飲むビールはスーパードライに限る。コーンスターチが入っているのがいいのかしら)箱根まわりを散策。平日なので人が少なくて、すれ違うのは老夫婦か学生が多い。

旅館に戻ってからは、また温泉に行ってサウナと沐浴の往復。

私は基本的に「緊張」が多く、そのぶん「脱力」するのに時間がかかる。だからサウナと沐浴を繰り返しやって、やっと精神に柔軟性が出はじめる。やるたびに「脱力」の大切さだったり、もうちょっと頻度を増やしたほうがいいよなー、など思う。

ちなみにうちのBを見てると、常に脱力できているのがわかる。脱力に関しては彼がいちばんの教師だ。

部屋に戻って、今朝進めていた作業のつづき。またPACKERSFUNの試合結果も更新。

今日やりたいことはすべて終わったので、今日も適当に飲みながら『アメトーーク』を観たり、新日本プロレスワールドを観たりした。ウィダインゼリーみたいな容器に入ったご当地ワインが、パッケージ込みでとても良かった。

そういえば新日本プロレスワールドの検索システムがどうにも使いづらくて困っていることを思い出した。どうにかできないかとメモしたところで酔いが回ってきたので就寝。

2020年10月7日、水曜日

久しぶりに二日酔いに似た感覚を覚えながら起床。すぐ朝ごはんをいただいて、空きがあったので貸切風呂も使わせてもらう。チェックアウトして、お土産を買って帰路につく(箱根てぃらみすを買おうと思っていたら今日は定休日だった。自分のくじ運の良さを忘れてた)。


GoToトラベルの感想。

混まなそうな平日を狙ったこともあり、とても気分よく過ごせた。そもそも出歩く予定でなかったらホテルにほぼいたけれど、温泉がほぼ貸切に近かったので、ゆっくりサウナと沐浴ができた(寝転がってやりたい派なので、人がいないのは本当にありがたい)。

もうホテル側もある程度業務フローが定着したのだろう。こちらは初めての「コロナ禍の旅行」なので変化を感じることは多くあったけれど、とくに違和感はなかった。なんなら夕食に最初からご飯が置かれているので、好きなタイミングでご飯を食べれた(たまたまご飯が食べたくて仕方なかったので嬉しかった)。

割引はされるし、3000円分のクーポンも使えるし(土産代or酒代に消えた)、余裕があるなら使うべきサービスだ。ここで使ったお金が巡ってくれればいいなと思う。Bを連れて行ける近場の旅館も探そう。


帰りの車内でPACKERSFUNの記事を書いて投稿。


帰宅後はBに久しぶりに会えて嬉しかったが、ものの数分で大変な生活が再開したことに気づいた。とはいえ一緒に『内村さまぁ〜ず』の有吉登場回を見直すなど、自分の好きなように一緒に過ごした。

夜になって新日本プロレスワールドの検索システムの準備をする。データは取得できそう(いまゆっくりスクレイピングをかけている)。

せっかくなら全文検索を導入したいなと思った。費用面がまだ判明していないが、ちょうどElasticSearchの学習にもなるし良いかと思う。

チラ見した感じではFirestoreにドキュメントを溜めて、それを何かしらの方法でElasticSearchに登録できれば、あとはトライ&エラーでなんとかなりそう。これを公開できるかどうかは別の問題。

2020年10月8日、木曜日

Bといっしょの朝が再開した。

新日本プロレスワールドの検索システムは、ElasticSearchを導入してみた。いい感じに検索できている。

これをどう公開しようか考えたが、費用が少ないのはやっぱりCloud Runだろうか。ElasticSearchのサーバと、ElasticSearchを操作するサーバを用意すればいいと仮定して作業を進めてみる。

色々と試行錯誤のすえ、なんとかCloud Run上で上記サーバーたちを動かすことができた。

ただCloud Runではすぐに初期化されてしまう(コンテナが消えてしまう)ため、Google App Engineで同様の構成で公開できないか試す。

そのなかで下記サイトが参考になりそうだったので、見様見真似でやってみる。

Ubuntu 18.04 に Elasticsearch をインストール

上記がうまくいかなかったので(デプロイはできたがアクセスがどうしてもできなかった)、KAGOYAのサーバに直接elasticsearchをインストールしてみる。

https://qiita.com/ekzemplaro/items/acc81bc96fdd56eed587

これもダメだったので、いっそCloud Runに初期データを与えようかと思い立ち実験。

ただこれも上手くいかなかった。スクレイピングを続けながら明日また考える。


PACKERSFUNは、プレイ分析の動画紹介をして投稿。

次作の翻訳ツールを使いながら進めたおかげで、以前より半分くらいの時間で仕上げることができている。

2020年10月9日、金曜日

起床してBと遊びながら、ベアーズ対バッカニアーズ戦を見る。ベアーズが4勝目。こうなるとは思ってなかった。

今日は株価予想プログラムを作ってみた。データの準備は上手くいったのだが、機械学習のところであまりおもしろい結果が得られなかった(どの日も「買うには自信がない」みたいな結果ばかり)。もうちょっと違うアプローチを考えたほうがよさそう。


夜はPACKERSFUNの記事を更新。ルーキーについて少し詳しくなった。

そのあと新日本プロレスの検索システムにめちゃくちゃ時間をつかってしまった。とりあえず動くものはできたが、なぜかローディング画面をつくれずに諦める結果に。


Week39

2020/10/03

今週のアウトプット

  • 予定
  • Google認証を実装する
  • 保育園の見学プランを立てる(残り分)
  • カウントアプリのページ遷移をつくる
  • 子どもの動画編集
  • 追加
  • TOEICテスト受験
  • 株式プログラム作成
  • 英文翻訳アプリ作成
  • コメントアウト翻訳モジュール作成

もともとやろうと思っていたカウントアプリを放って、株式と英語関連のアプリ作成に没頭した。先週GCPを覚えたのがめちゃくちゃデカい。それぞれプロトタイプは出来上がったので、ここからは少しずつ改修をしていこうと思う。

2020年9月26日、土曜日

今日も雨。Bは秋服に衣替えした。

最近22時には寝るので、録画しておいた『脱力タイムズ』を見る。毎週「当たり」の内容だけど、今週は「大当たり」だった。ポケモン風に言えば、「コンプライアンス」タイプの世の中に対して、「有田」タイプの攻撃は2倍の威力になる。つまり「時代に合っている」ということ。

Bを朝寝させたら、簡単な週次レビューを終えて、Google認証に取り組んだ。react-firebaseuiというfirebaseUIをReact用にラッパーされたモジュールがあったのでこれを利用したらサクッといけた。ただページ遷移を考えていないので、めちゃくちゃなログイン後の導線が出来上がってしまった。


13時からはオンラインでTOEIC L&Rテストを受講する。

Zoomにログインしたら他の参加者のフルネームがばんばん飛び出てて、ちょっと動悸がした。おじさんは別にいいけれど、若い娘はちょっとリテラシー上げたほうが安全。それかTOEIC運営側がミーティング参加する前の注意事項として周知するか。

実際のテストは、まったく勉強していない状態でどうなるか不安なまま終わった。700点は超えてると思うけど、最高点ではなさそう。


Bを寝かしつける合間に『キングオブコント2020』を観る。今年はすごい期待していただけに、ちょっと盛り上がりには欠けてしまったか。個人的にはうるとらブギーズが面白かった。

google domainsにドメインを移管したらネームサーバーの設定を誤っていて繋がらない時間帯があった。復旧は解消。

また保育園のお知らせの更新を知りたかったので、早速Cloud Runを使って自動で更新の確認・通知機能を稼働させた(保育園のサーバに迷惑のかからない頻度=1時間に1度チェックする)。1時間もかからずに準備できたので、バックエンドは結構いい感じになってきたかな。Kagoyaで運営していたサービスも移行しようと思う。

2020年9月27日、日曜日

雨が振らないうちにBを連れて散歩に。

有価証券報告書をAPI経由で取得するライブラリが使えなくなっていたので、自分でどうにかすることに。

ものすごし集中してしまい(良いような悪いような気持ち)、一気に分析プログラムをアップデートさせた。具体的には長期保有できる株かどうかを分析できるように、過去の有価証券報告書もFirestoreに保存させるようにしている。

問題はデータ量や読み書きの数が無料範囲を超えそうなところ。月1ドル程度の出費に抑えられるように検討しよう。

2020年9月28日、月曜日

パッカーズ戦があるため、今日はBの散歩を昼に回す。せめてもの償いに家でいっしょに遊ぶ。

試合は最終クォーターまでもつれながらも、最後は無事勝ちきった。セインツのRBカマラが超人すぎて、ほぼパッカーズvsカマラの勝負だった。詳細はPACKERSFUNにて。


昼間はあたたかくなってきたので、Bを連れて散歩。新しいカフェに行ってみる。アイスコーヒーがとても濃かったので、数年ぶりにコーヒーフレッシュを入れる。油の味に変わってしまって反省。もう二度とこんなミスはしない。


夜に株式アプリをすこし改修。データの持ち方を証券コード別にした。

2020年9月29日、火曜日

株式アプリにちょこちょこ手入れ。必要なデータをだいたい取得できたので、分析をしてみる。自分の保有している株が7年後は51円になっていると伝えられショック。

バッチ処理も作成して、その日に発表された有価証券報告書の中にいい銘柄がないかを検索できるようにした。なにかあればSlackに通信して、詳細を調べたければSlackに載せたURLを見ればいい、ということにした。上手くいけばいいなー。


昼のあたたかいうちにBを連れて散歩。ちょっと前までは暑いのを気にしていたのに、今日は寒さを気にするように。「ちょうどいい気候」が毎年ちょっとずつ減っている。仕方がない。

2020年9月30日、水曜日

エアコンの掃除業者が来てくれるので、さきに部屋の掃除。昼ごろに来てくれて、すぐにやってくれた。8000円也。

PACKERSFUNは、Week3のまとめ記事を執筆。ついでにプレイ分析動画の翻訳も済ませた。

そのなかで英文読解の手助けになるツールをつくりたくて、もう5度目ぐらいではあるがチャレンジ(実務においてはDeepL翻訳でほぼOK。しかしあまりにもブラックボックス化していて、自身の英語スキルはいっさい上がらないことに気づいた)。

最近よく書いているように、“FastAPI + Cloud Run”と”React”で構成はすぐ準備。今回は自然言語処理のモジュールnltkをはじめて使ってみた。それを使って各英単語を次のとおりに分析した。

  • NGSL登録語かどうかの判定* 品詞抽出* 固有名詞かどうかの判定それでこれをフロントに上手く反映させて読解の手助けにしたいと思っているのだが、肝心のフロントをどう表示させるか迷った。

つまりは「英文をどう読めば(把握すれば)いいか」という問題で、結局英語の勉強をしないといけない。

2020年10月1日、木曜日

朝が寒くなってきた。

Bは最近モノで遊ぶようになってきた。ガラガラを振ったり。振っているうちに意図せず投げ捨ててしまっているので、これがいつ自分の意図で捨てるようになるのか観察しよう。


PACKERSFUNは、Week4のプレビューを書く。ファルコンズ戦だが勝てる気がしてきた。

また英文を読むために、昨日つくったツールを少しイジった。いろいろと悩んだ結果、

  • 名詞* 動詞* 接続詞* 前置詞にハイライトをかけ、ほかをグレーアウトしてみたところ、すこし読みやすくなった。ポイントになる単語だけが浮かんできて、かつ文を区切れる感覚。

またNGSLの単語リストを引っ張ってきて、この中に含まれているのに覚えていない単語を抽出するようにした。サンプルとしていろんなテキストを読みながら見つけていく予定。

そのなかでReactアプリケーションを作るときにcreate-react-app通称CRAを使っているのだけれど、これと普通のreactの違いがわからなかった。next.jsの違いも理解してない。

2020年10月2日、金曜日

Bの寝そうなタイミングが身体的に把握できてきた。なんとなく「あ、もう寝るな」というときを感じて、適当に抱っこしていると寝てくれる。いつも思うけど、あくびした直後に寝るなんて本当にすごいと思う。教えてほしいぐらい。

フロントエンドをもう少し鍛えないといけないと感じ、Reactを本格的に学ぶことを決意。あとサボってたLinuCの勉強を復活。今年の終わりには 自分でサービス開発ができて、インフラ(Linux)まわりも喋れる ぐらいになれればいいかなと思う。

今日はCRAで使われているモジュールを確認し、そのうち必須のモジュールだけで最低限のReactアプリを作成した。


上記のReactの学習用に、コメントアウトだけを翻訳するモジュールを作成してみた。

個人的にはかなり便利なツールが作れたと思う。Qiitaにも投稿。

来週のアウトプット

  • Reactまわりを勉強する(3ヶ月ぐらいかかりそう)
  • React
  • React Hooks
  • Next.js
  • webpack
  • babel
  • みずほ銀行の株価予想プログラム
  • 1日/n日平均の上昇率
  • 現在の株価とn日平均の乖離率
  • 【結果】翌日の初値と終値の差(プラスorマイナス)
  • 上記をもとにして機械学習で読ませる
  • Cloud RunからGmailを使う

Week38

2020/09/26

週次レビューを再開したので、ついでにこちらにも書いておく。

今週のアウトプット

PACKERS FUNの更新

今週からスタートしたNFLについて、シーズン全体の記事と試合に関する記事など。先々週とあわせて10記事以上を更新。

AWSチュートリアルを終える

チュートリアルを読みながら、ウェブサイトの構築を行った。

AWSの概要はなんとなく理解したが、CloudFormationのテンプレートを理解していないので実践で使うには勉強が足りなそう。とはいえ人と話すときには困らなくなった。

それよりもAWSは個人で使うにはお金がかかるので、基本無料で使えるGoogle Cloud Platform(GCP)をキャッチアップした。末尾の日記の通り、GCPをつかってアプリを構成することができた。ほぼこれでよさそう。

保育園の見学プランを立てる

大体立てた。ビックリしたのは見学概要がサイトに掲載されてから数時間で予約が埋まってしまったこと。スクレイピングでページ更新を確かめようかどうか迷っている。

子どもの動画を集めなおす

Dropboxと簡単なプログラムを使って、簡単にHDDへ転送するようにした。このうち「使う動画」や「使える時間」をまとめておきたいなと考えている。

いま求められているスキルを調べる

最近の求人情報をちょっと確認。やっぱりAWS系の知識が優遇されている。GCPの知識をつけておいて、クラウド全体の知識として自己紹介できればいいかな。あとはPM経験。

それほど「そんな知識/経験が!」というのはなかったので、いったんはもういいかな。

2020年9月19日、土曜日

Bを連れて散歩。予定通り寝てくれたが、今日は1時間近く寝てくれたことにビックリ。その間に週次レビューを復活させ(上記の通り)、来週の目標を決めた。

そのあとTodoistを自分好みに使うために、簡単なプログラムを作成した。Pythonのライブラリがボランティアで提供されているので、30分もあれば作ることができた。

お昼ころ、はじめて離乳食を食べさせてみた。思ったよりも食べてくれて順調。口の中に入れるだけでも立派だと思う。


これまで撮影した写真や動画の整理について悩む。とりあえず写真や動画を保存するとして、

  • どのようにスマホ(またはデジカメ)の写真をHDDへ移動するか* これをどのように流れ作業にするかというところで色々と考えた。いろいろと試してみた結果、(スマホは)Dropboxに同期させつつ、適当な間隔でこれをゴッソリHDDに移すことにした。

その際、日付ごとに整理したくなったので、Todoist同様にPythonのプログラムをちゃちゃっと書く。これで思いたったときにHDDを接続してプログラムを走らせれば自動的にHDDへ保存ができるようになった。

ここまでいくと、NATを導入して適宜HDDにコピーするようにしたくなってきた。次のセール期間はNAT導入を検討しよう。

みたいなことをやっているうちにもう夜。新日本プロレスG1 CLIMAXの開幕戦を見つつ(オスプレイのヘビー転向は成功したと思う)、パッカーズの直前情報を確認。ブログにして寝る。

2020年9月20日、日曜日

雨を気にして自宅で過ごす。Bはずっと「クマーバチャンネル」を見ている。私の時代とくらべて最近のキッズソングは低音が出ていると思う。

AWSのチュートリアルはDBの追加に進んだ。そのままユーザ認証もチャレンジしてみる。認証メールの本文が味気なくスパムっぽく見えたので、実際に使う場合は修正しないといけなさそう。

配偶者がLINEスタンプを作っているので、「画像をLINEスタンプの形式に変換できれば楽なのにな」と思って調べてみたら、やっぱり既にやっている人がいた。

上記を参考にさせてもらいつつ、クロップ機能も追加してライブラリを作った。スタンプ画像ができあがったら実際に使ってみてもらって上手くいくかテストする予定。

2020年9月21日、月曜日

起床後、Bと一緒にパッカーズの試合を観る。結果は圧勝。最終クォータはBの面倒を見ながら横目で観戦する程度だった。

試合結果のブログも書き終えると昼間だったが、涼しいので散歩に出かける。忘れてたけど今週は4連休で、人出はほとんど元に戻ってきた感じ。休日はふつうに働いている人たちのものだと思うので、なるべく邪魔をしないように散歩して、公園ですこし寝てもらって帰宅。

配偶者がNetflixで江原啓之MCのスピリチュアル番組を見つけた。出演者の中に澤穂希がいて驚いたが、それよりもアシスタントが住吉美紀だったことに震える。

ふと最近の転職事情を知りたくなって、いくつか求人情報を確認してみた。やっぱりAWSが求められてるんだなと実感。あとはリーダー経験とか。そろそろ「経験」でご飯を食べるフェーズに入ってきている。

2020年9月22日、火曜日

起床後、AWSチュートリアルをやる。とりあえず終わった。各サービスのイメージを掴めたかな、という程度。請求がすごいきて驚いた(1日4ドルぐらい)。

感覚はつかんだので、GCPでもやってみようと思う。個人用のPythonのテンプレートを準備したあと、ためしにCloud Functionsを使ってみた。

最初の関数: Python  |  Google Cloud Functions に関するドキュメント

gcloud経由で操作するにはCloud Build APIを利用する必要があるみたいなので、APIを有効にした。

時間があったので、Cloud Firestore を使ってみる  |  FirebaseでFirestoreとの連携も試してみる。とりあえず上手くいった。

わからないのはGCPとFirebaseの関連性について。GCPがFirebaseを包括しているようなイメージだけど、勘違いしていそう。困ったときにちゃんと調べるか。

夜はCloud Runを触ってみる。Cloud Build、Container Repositoryあたりを使ってDockerイメージからCloud Runのサービスを起動できた。いい感じ。

明日以降にCloud RunからCloud Firestoreを触ることができれば(今日作成したコレクションを利用しよう)、簡単にAPIをつくることができそう。フロントエンドはFirebaseかNetlifyでいこうか。

2020年9月23日、水曜日

雨が降るそうだったのでBの散歩は諦める。

一緒に『ロンドンハーツ』を見ていたら、炎上騒ぎのあったシュウペイに対して有吉から「間違った意見に屈するな」の一言。ちょっといいシーンだったし、世代の断絶にも気づくシーンだった。


GCPはCloud RunからFirestoreに接続させることもできた。せっかくなのでFastApiを使ったテンプレートプロジェクトを作ろうと思う。

Firestoreについて調べていたら、「FirebaseのCloud Firestoreを発展させて、最近GCPのCloud Firestoreができた」という旨の記事を読んだ。少し納得。ドキュメントの位置がわからなくなるので、こっちにリンクを張っておこう。

Firestoreのドキュメント

ちなみに現在はDatastoreでなく、Firesotreを利用しているはず。この差もいずれ重要になるかもしれないが、いまは無視しておく。

認証情報まわりでミスった(誤ってキーをレポジトリにアップしてしまっていた)ので、その解決策を検討。

どうやら同じプロジェクト(正確にはサービスアカウントだと思う)なら認証情報の受け渡しが不要みたい。そのため開発環境ではキーを利用して、本番環境はGoogleに任せるようにした。


テレワークが進んだおかげで、育休中も会社の情報が追いやすくなった。

気持ちを切り替えるためにまったく見ないようにしていたが、大きな全社イベントがあったので、その映像を見る。


今日一日でGCPについては割と詳しくなった気がする。明日は時間をつくってAPIサーバの公開をドキュメント化・テンプレート化しよう。

またpackersfun.comをGoogleDomainに移管した。このkoboriakira.comも移管する予定。

2020年9月24日、木曜日

珍しくBが大泣きした。散歩に連れていけれないからだろうか。どちらにせよ活動時間がオーバーしていたので頑張って寝てもらった。

GCPを使ったAPIサーバは、最終的に下の技術を使うことにした* FastAPI: PythonのAPIサーバ* Docker: コンテナ* git: リビジョン管理* Google Cloud Run: コンテナのデプロイサービス* Google Cloud Builder: CD/CIサービス* Google Container Respository: Dockerイメージ管理サービス* Google Cloud Firestore: データベースとりあえずメモ。

0. 前提

Docker、gcloudはインストールしておいてもらう。

bash $ docker --version Docker version 19.03.12, build 48a66213fe $ docker-compose --version docker-compose version 1.26.2, build eefe0d31 ``````bash $ gcloud --version Google Cloud SDK 311.0.0 bq 2.0.60 core 2020.09.18 gsutil 4.53 ### 1. プロジェクトを作成するmy-awesome-apiという名前でプロジェクトを作成した。次のキーを混同しないように。

  • プロジェクト名: my-awesome-api * プロジェクトID: my-awesome-api-290501 * プロジェクト番号: 359948014733 ### 2. gitリポジトリを作成、クローンするawesomeapiという名前でgitリポジトリを作成した。

bash mkdir ~/git cd ~/git git clone git@github.com:koboriakira/awesomeapi.git cd awesomeapi ### 3. Dockerコンテナ内でFastAPIサーバを立てるDockerfileをつくって、イメージをbuildして、コンテナをrunする。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ``````bash docker build -t awesomeapi-image .

docker run -v $(pwd)/awesomeapi/:/work/awesomeapi -p 7777:8000 -it —rm —name awesomeapi-container awesomeapi-image /bin/bash ```ファイルを作成して、Dockerコンテナ内にもファイルが共有されていることを確認する。

ローカル上にawesomeapi/main.pyを作成。


├── Dockerfile ├── README.md └── awesomeapi └── main.py ``````python main.py from typing import Optional from fastapi import FastAPI app = FastAPI()

@app.get("/")

def read_root():return {"Hello": "World"}@app.get("/items/{item_id}")

def read_item(item_id: int, q: Optional[str] = None):return {"item_id": item_id, "q": q}```Dockerコンテナ内で、ファイルを確認。

```bash # pwd work # ls awesomeapi main.pu ```Dockerコンテナ内で、必要なPythonライブラリをインストール。

```bash # 先にpip自体のバージョンを最新化$ pip install --upgrade pip $ pip install fastapi uvicorn ```Dockerコンテナ内で、FastAPIサーバを起動。

```bash $ uvicorn awesomeapi.main:app --host 0.0.0.0 --reload ````http://localhost:7777/`にアクセスして、Docker内の`localhost:8000`に立てられたFastAPIサーバと疎通できていることを確認。

具体的にはブラウザに`{"Hello":"World"}`と表示されるはず。これがレスポンス。

ためしに`main.py`の`read_root`メソッドにある`{"Hello":"World"}`を編集してブラウザをリロードしてみる。するとレスポンスも変わるはず。

### 4. Docker ComposeでFastAPIサーバを起動する

コンテナ内に入らずに開発できるようにする。

まず必要なPythonライブラリを`requirements.txt`にまとめる。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── __pycache__ (以降は省略)

│   └── main.py └── requirements.txt ``````requirements.txt fastapi uvicorn ```次にrequirements.txtをDockerイメージ内に追加してライブラリをインストールするように、Dockerfileに追記する。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt ```さらにDockerコンテナを起動したときにFastAPIが起動されるように追記する。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--reload"]```新しいDockerイメージをbuildして、そのイメージからコンテナをrunする。`docker run`の末尾の`/bin/bash`がなくなったことに注意```bash docker build -t awesomeapi-image .

docker run -v $(pwd)/awesomeapi/:/work/awesomeapi -p 7777:8000 --rm --name awesomeapi-container awesomeapi-image ```最後に、これらのDockerイメージのbuild・コンテナのrunを簡単にするためにDocker Composeを使う。

次のようなdocker-compose.ymlを作成して、`docker-compose up`で起動```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   └── main.py ├── docker-compose.yml └── requirements.txt ``````docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8000'volumes:- ./awesomeapi:/work/awesomeapi ``````bash docker-compose up ```同じく`localhost:7777`にアクセスでき、`main.py`を編集すれば反映されることを確認。

ここまでで、(データベースを使わない)APIサーバの開発環境を作成することができた。いったんgitリポジトリにコミット。

```bash git add .

git commit -m "Initial Commit"git push origin master ```### 4. Google Cloud Runにデプロイしてサービスを公開するCloud Runに移動して、「サービスを作成」をクリック。

* リージョン: asia-northeast1 * サービス名: awesomeapi * 「未認証の呼び出しを許可」

「次へ」をクリックしたあと、「コンテナイメージのURL」でawesomeapi-imageのlatestを選択。

すると自動でGoogle Cloud Buildをつくってビルド、デプロイをしてくれる。

しかしこの状態では失敗する。Cloud RunでDockerを使う場合は8080ポートで通信を待つ必要があるからだ。

そのためDockerfileを修正して、gitにpush。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--port","8080"]```ビルドが自動開始するのを確認。完了したらCloud Runに戻って、Cloud RunのURLに飛ぶと、同様のレスポンスを取得できる。これでサービスが公開された。

## 5. FirestoreをつかってNoSQLを利用できるようにする

Google Cloud Firestoreに移動。「ネイティブモードを選択」をクリック。リージョンはasia-northeast1にして「データベースを作成」をクリック。

先にコレクションを作ってしまう。テストで次のようにした。

* コレクションID: users * ドキュメントID: 自動割り当て* フィールド:* name: koboriakira (フィールドタイプ string)

* age: 31(フィールドタイプ number)

つぎにFirestoreのデータを読み取れるように実装を進める。

```requirements.txt fastapi uvicorn google-cloud-firestore ``````main.py from typing import Optional from fastapi import FastAPI from google.cloud import firestore app = FastAPI()

db = firestore.Client()

@app.get("/")

def read_root():docs = db.collection(u'users').stream()

result = {}for doc in docs:result[doc.id] = doc.to_dict()

return result @app.get("/items/{item_id}")

def read_item(item_id: int, q: Optional[str] = None):return {"item_id": item_id, "q": q}```いったんローカルのテストは無視して、`git commit`そして`git push`する。Cloud Buildが自動的にスタートする。

ビルドが成功してCloud Runのコンテナが最新化したことを確認したら、サービスのURLに飛ぶ。

レスポンスが`{"4Ja4sXQ6DiIDX3N0kYmW":{"age":31,"name":"koboriakira"}}`のようになっていれば、データベースを利用できていることがわかる。

### 6. Firestoreをつかった開発環境をつくる

さきにdocker-compose.ymlのportsも8080に修正しておく。

```docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8080'volumes:- ./awesomeapi:/work/awesomeapi ```つぎにこのFirestoreを扱えるように認証まわりの設定をする。

「IAMと管理」 > 「サービスアカウント」に移動。`<プロジェクトID>@appspot.gserviceaccount.com`というアカウントがあるはずなので、クリックしてアカウント詳細画面へ。

画面下の「キー」で「鍵を追加」をクリック。JSONでキーを作成すると、jsonファイルがローカルに自動でダウンロードされる。

このファイルを内に配置し、誤ってpushしないように.gitignoreを編集する```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── __pycache__ │   │   └── main.cpython-38.pyc │   └── main.py ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json └── requirements.txt ``````.gitignore # credentials my-awesome-api-290501-9b5ca70ce0e8.json (以下省略)

```念のため`git status`でjsonファイルがgit管理対象でないことを確認しておく。

このjsonファイルをDockerコンテナに入れたいので、docker-compose.ymlを編集する。

```docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8080'volumes:- ./awesomeapi:/work/awesomeapi - ./my-awesome-api-290501-9b5ca70ce0e8.json:/work/credentials.json environment:- GOOGLE_APPLICATION_CREDENTIALS=/work/credentials.json ```※Dockerfileにjsonファイルを含めるような編集をすると、のちの自動ビルド時にjsonファイルが見つからないためエラーになる。

`docker-compose up`でコンテナを開始して、`localhost:7777`にアクセスして、同様にデータベースを使っていることを確認する。

## 7. ビルド構成をファイル管理する

Google Cloud Buildの「トリガー」に移動して、作成されたトリガーの詳細に移る。

`cloudbuild.yaml`を作成し、詳細内にある「インライン」で定義されている設定ファイルの記述をコピペする。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   └── main.py ├── cloudbuild.yaml ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json └── requirements.txt ``````cloudbuild.yaml steps:- name: gcr.io/cloud-builders/docker args:- build - '--no-cache'- '-t'
- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- .
- '-f'
- Dockerfile
id: Build - name: gcr.io/cloud-builders/docker args:- push - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'id: Push - name: gcr.io/google.com/cloudsdktool/cloud-sdk args:- run - services - update
- $_SERVICE_NAME
- '--platform=managed'
- '--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- >-
--labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS
- '--region=$_DEPLOY_REGION'
- '--quiet'
id: Deploy entrypoint: gcloud images:- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'options:substitutionOption: ALLOW_LOOSE substitutions:_TRIGGER_ID: 33942bf8-952d-4bf8-8bf0-52dd2d45409d _SERVICE_NAME: awesomeapi _DEPLOY_REGION: asia-northeast1 _GCR_HOSTNAME: asia.gcr.io _PLATFORM: managed _LABELS: gcb-trigger-id=33942bf8-952d-4bf8-8bf0-52dd2d45409d - gcp-cloud-build-deploy-cloud-run - gcp-cloud-build-deploy-cloud-run-managed - awesomeapi
```Google Cloud Buildのビルド構成を「インライン」から「Cloud Build構成ファイル」に変えて「保存」をクリック。

## 8. テストを作成して、CIを整える

テスト用に適当なメソッドをつくる。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── calculate.py │   └── main.py ├── cloudbuild.yaml ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json ├── requirements.txt └── tests └── test_calculate.py ``````calculate.py def add(a: int, b: int) -> int:return a + b ``````test_calculate.py from awesomeapi import calculate def test_add():assert calculate.add(2, 3), 5 ```ローカルでpytestを実行。

```bash $ python -m pytest ========================== test session starts ===========================platform darwin -- Python 3.8.2, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 rootdir: /Users/canary/git/awesomeapi collected 1 item tests/test_calculate.py .                                          [100%]=========================== 1 passed in 0.02s ============================```Docker上でもテストが行えるように、pytestをライブラリに追加し、testsフォルダをDockerイメージに追加する。

```requirements.txt fastapi uvicorn google-cloud-firestore pytest ``````Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD tests /work/tests ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--port","8080"]```cloudbuild.yamlを編集して、テストを追加する。

```cloudbuild.yaml steps:- name: gcr.io/cloud-builders/docker args:- build - '--no-cache'- '-t'
- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- .
- '-f'
- Dockerfile
id: Build - name: gcr.io/cloud-builders/docker args:- run - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'- python
- -m
- pytest
id: Test (以下略)

```gitにコミットして、Cloud Buildを走らせる。ビルドが通ればテストの自動実行設定もできた。

### 9. このあとやりたいこと

* ビルド結果をSlack等に通知* そのアプリをつくる?

* またはPubSubを勉強する必要がありそう* ストレージに保存したい* 保存はできた。バゲットを示す環境変数はCloud Runにも必要* svgを作成して保存したりしたい* svgは別途勉強しないといけない
---

パッカーズ対セインツのプレビューを書いて(あまり深い内容にならなくて反省)、とりあえず今日は終わり。明日以降はフロントエンドをやりなおして、APIサーバを利用したサイトを作ってみて終わり。

## 2020年9月25日、金曜日

今日も雨でBと散歩には行けなさそう。

ドルフィンズ対ジャガーズの試合をチラ見しながらReactとCircleCIの導入にチャレンジ。またkoboriakira.comをGoogle Domainsに移行した。サブドメインを使ったアプリ公開が楽になりそうなので嬉しい。

---

個人開発に関して、すこしまとめておこうと思う。

* 管理* masterブランチとfeatureブランチで運用する* masterブランチにコミットしないようpre-commitを利用する* masterブランチにはPRでマージする* CircleCIを利用して、各コミットごと(PRごと)にテストを回す* フロントエンド* React + TypeScriptで開発* masterブランチをNetlifyにデプロイして公開する* バックエンド* Google Cloud Runを利用して、REST APIでサービス公開する* Cloud Runには、Google Cloud Build(Google Container Repository)を利用して自動デプロイを整える* データベースはGoogle Cloud Firestore、ファイル管理はGoogle Cloud Storageを利用する* 今後のチャレンジ* フロントの認証機能をつける* ネットワークやロギングについて改善できることがないか調べる* CIにおいて、テスト結果をSlackなどに連携させる* 上記のプロジェクトのテンプレートを用意する* Firestore、NoSQLを使ったモデリングのベストプラクティスを学ぶ* 他のGPCのサービスを利用する* gRPCを学ぶこの数週間で個人でアプリケーション開発ができる状態にはなってきた。一方で運用フェーズでは必ず問題点が発生しそうな気がしている。なのでさまざまなことを出来るようにしつつ、公開後に必要となる知識もすこしずつ触れてみようかなと考えている。

とりあえずFirebase Authenticationを使って会員登録/ログイン機能を実装してみて(以前にやったけどもう忘れていた)、いよいよアプリケーション開発にとりかかる。シンプルなカウンターのアプリにするつもり。

## 来週のアウトプット

- Google認証を実装する
- カウントアプリのページ遷移をつくる
- 保育園の見学プランを立てる(残り分)
- 初日と2日目のパートをつくる
- 試合に関する情報を集める
バックエンドはなんとか最初のステージを突破したので、フロントエンドを再学習しながらアウトプットに努める。

はじめに

Amazonが提供する現代的なウェブアプリケーションの構築を読み進めることにした。

なお実践はCloud9ではなくローカル端末で試すことにした。

また請求が発生する可能性があるため、早めに済ませること。EC2でめちゃくちゃお金がかかった。

モジュール1「静的ウェブサイトの構築」

(前提)AWS CLIの設定

AWS CLIを使う必要があるのでaws configureでAWSの設定ファイル(.aws)を作成した。アクセスキーが古くなってきたので新しくした。

(前提)S3とは

S3 は、保存されたオブジェクトをHTTP経由で直接提供できる、耐久性と可用性に優れた、低コストのオブジェクトストレージサービスです。

「ファイルをHTTPで転送できる」というのがポイント。つまりWebサイトにもなりうる。

S3バケットの作成

aws s3 mbコマンドでS3バケットを作成した。バケット名はaws-modern-application-workshop-koboriにしたので、具体的には次のコマンドを打つ。

bash aws s3 mb s3://aws-modern-application-workshop-kobori ### S3バケットの設定静的ウェブサイトのホスティングができるように、「ウェブサイトとして利用」と「外部からのアクセスを許可」の設定をする。

ホスティング

aws s3 websiteコマンドで静的Webサイトのホスティング設定をする。--index-documentオプションはindex.htmlを指定。

外部からのアクセスを許可

バケットを作成した時点ではプライベート(外部からはアクセスできない)ため、S3バケットポリシーを変更する必要がある。

バケットポリシーは一般的にはJSONファイルを定義して、これをaws s3api put-bucket-policyコマンドで送るのがいいみたい。そのためJSONファイルを次のように送ったbash aws s3api put-bucket-policy --bucket aws-modern-application-workshop-kobori --policy file://JSONファイルJSONファイルの中身は下記の通り。

json {"Id": "MyPolicy","Version": "2012-10-17","Statement": [{"Sid": "PublicReadForGetBucketObjects","Effect": "Allow","Principal": "*","Action": "s3:GetObject","Resource": "arn:aws:s3:::aws-modern-application-workshop-kobori/*"}]}### index.htmlをデプロイ最後に実際に利用されるindex.htmlをS3バケットに配置する。これはaws s3 cpコマンドで設定。

cpコマンドと同じなので、具体的には次のようにした。

bash aws s3 cp ローカルのindex.html s3://aws-modern-application-workshop-kobori/index.html これでウェブサイトが構築できた。というかこんなに簡単なのか。心配なのは金額だけ。

調子がよかったので「モジュール 2: ウェブサーバーでのアプリケーションのホスト」もちょっと読んでみよう。実際のメモは明日以降に。

モジュール2「静的ウェブサイトの構築」

(前提)各サービス、用語の概要

  • AWS CloudFormation: Amazon Web Servicesリソースのモデル化およびセットアップのサービス。インフラストラクチャ管理を簡略化する。

  • NLB: Network Load Balancer * Amazon ECR: Elastic Container Registry、完全マネージド型のDockerコンテナレジストリです。このレジストリを使うと、開発者はDockerコンテナイメージを簡単に保存、管理、デプロイできます。

  • Amazon ECS: Elastic Container Service、フルマネージド型のコンテナオーケストレーションサービスです。

  • AWS CodeCommit: Gitベースのリポジトリをセキュアにホストする完全マネージド型のソース管理サービスです。

  • AWS CodeBuild: ソースコードをコンパイルし、テストを実行し、デプロイ可能なソフトウェアパッケージを作成できる完全マネージド型のビルドサービスです。

  • AWS CodePipeline: 完全マネージド型の継続的デリバリーサービスで、素早く確実性のあるアプリケーションとインフラストラクチャのアップデートのための、パイプラインのリリースを自動化します### モジュール2A: CloudFormationのテンプレートをデプロイするaws cloudformation create-stackコマンドで、ローカルにあるテンプレートのymlとIAMリソースをつかってスタックを作成する。

bash aws cloudformation create-stack --stack-name MythicalMysfitsCoreStack --capabilities CAPABILITY_NAMED_IAM --template-body file://module-2/cfn/core.yml スタックとは、

スタックは、単一のユニットとして管理できる AWS リソースのコレクションです。 つまり、スタックを作成、更新、削除することで、リソースのコレクションを作成、更新、削除できます。 … リソースが作成できない場合、AWS CloudFormation はスタックをロールバックし、作成されたリソースを自動的に削除します。

ちなみにスタックをつくるときにIAMロール(ポリシー)でつまづいた。EC2とIAMに関してフルアクセスの権限を付与して解決したが、ベストプラクティスがわからない。このあたりを勉強すべきか迷う。

モジュール2B: サービスをNLB経由でデプロイ・公開する

aws ecr create-repositoryコマンドでリポジトリを作成する。AmazonEC2ContainerRegistryFullAccessの権限を付与して実行した(FullAccessがベストではない気がするのだが、コマンドとポリシー、パーミッションの関係が見つけられない)。

このあとDockerログインをするのだが、aws ecr get-loginコマンドはセキュリティの関係から(コマンド履歴にパスワードが残る)使えなくなっていた。そのためこちらを参考にして、aws ecr get-login-passwordコマンドでdocker loginを進めた。IssueかPRを出せるといいな。

つぎにECRにプッシュしたイメージをECSにデプロイする。

aws ecs create-clusterでサーバのクラスター、aws logs create-log-groupでロググループをそれぞれ作成する。

与えられたテンプレートを使って、aws ecs register-task-definitionコマンドでECSタスク定義を登録する。

つぎにサービススタックに必要なインフラストラクチャをプロビジョニングする。

プロビジョニングとは、必要に応じてネットワークやコンピューターの設備などのリソースを提供できるよう予測し、準備しておくことです
https://www.idcf.jp/words/provisioning.html

ただ単純に公開するのではなくNLBをかませることで、実際のサービスのスケールイン/スケールアウトを容易にできる。

というわけでaws elbv2 create-load-balancerコマンドでロードバランサーを作成する。サブネットはCloudFormationで作成したスタックから利用。

次にaws elbv2 create-target-groupコマンドでNLBターゲットグループ、aws elbv2 create-listenerコマンドでNLBロードバランサーのリスナーをそれぞれ作成。これで80番ポートが受信したリクエストをターゲットグループに登録されているターゲットに転送することをロードバランサーに知らせる。あまり意味はわかっていないけど、とりあえず書いておこう。

よくわからないけど、はじめてECSを利用する場合はaws iam create-service-linked-role --aws-service-name ecs.amazonaws.comが必要なよう。

ECSで実際のサービスを作成するため、aws ecs create-serviceコマンドを実行するaws ecs create-service --cli-input-json file://service-definition.json これで実際のサービス(Flask)にNLBを介してアクセスできるようになった。NLBのDNSでcurlを飛ばしてみると、実際にレスポンスが帰ってくる。

ちなみに最初に時間がかかったのはコンテナを作成・起動しているからか。2度目は一瞬だったので。

このサービスを利用するようにフロントエンドのindex.htmlを修正して、モジュールBは終了。

モジュール2C: CD/CIの設定

上記のまま開発を続けると、デプロイする際にはイメージを更新、プッシュして、またタスク定義を更新しないといけなさそう(その方法はチュートリアルにない)。

そのためCD/CIを設定する。

まずCI/CDアーティファクト用のS3バケットをつくる。バケットポリシーはチュートリアル側で用意してくれたものを使う。GETとPUTを許可しているみたい。

つぎにaws codecommit create-repositoryでCodeCommitリポジトリ、aws codebuild create-projectでCodeBuildプロジェクトを作成。いろんな値をコピペするので忘れても調べられるようにしないといけないな。

最後に、CodeBuildプロジェクトを使用してCodeCommitリポジトリを継続的に統合することと、新しくビルドされたアーティファクトをECSのサービスに継続的に提供するサービスとして、AWS CodePipelineをつくる。

aws codepipeline create-pipelineコマンドで、CodePipelineのパイプラインを作成。

そしてCodeBuildがECRリポジトリにアクセスできるよう設定する。具体的にはaws ecr set-repository-policyコマンドでECRリポジトリのポリシーを設定する。

これで使えるようになったのでテストをする。gitの認証まわりに関する設定を行った後、codecommitの空リポジトリをクローンして、今回のアプリケーションのソースをcommitしてpush。

CodePipelineのコンソールで自動ビルドが行われていることを確認して完了。

モジュール3「情報の保存」

テーブル、データの追加

aws dynamodb create-tableコマンドでデータベースを作成。aws dynamodb scanコマンドでテーブルの中身が見れる(見れるということは作成に成功している証拠)。

aws dynamodb batch-write-itemコマンドでレコードを追加する。scanして追加されたことを確認。

ウェブサイトの更新

つぎにこのDBを使うようにアプリを直してcommit, pushしたのだが、403エラーで失敗してしまった。

どうやらHTTPSでやるとMacのキーチェーンの問題があるようなので、SSHを使って回避するようにした。具体的には、

  1. IAMユーザの「AWS CodeCommit の SSH キー」に公開鍵を設定する
  2. SSHキーIDが発行されるので、これを使った~/.ssh/configを設定(下記参照)
  3. ssh git-codecommit.ap-northeast-1.amazonaws.comで疎通確認

~/.ssh/config Host git-codecommit.*.amazonaws.com User <SSHキーID>IdentityFile ~/.ssh/id_rsa またフロントのindex.htmlも更新。

パイプラインが成功したらサイトを確認。API、DBを使ってリストを描画していることを確認して終了。

モジュール4「ユーザ登録の設定」

(前提)Amazon Cognitoとは

ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加する。

ユーザプールの作成

aws cognito-idp create-user-poolコマンドで、Cognitoユーザープールを作成する。オプションも入れると次の通り。

bash aws cognito-idp create-user-pool --pool-name MysfitsUserPool --auto-verified-attributes email またユーザプールとセットで、aws cognito-idp create-user-pool-clientコマンドで、ユーザープールクライアントも作成する。

bash aws cognito-idp create-user-pool-client --user-pool-id <ユーザプールのID> --client-name MysfitsUserPoolClient “Id”: “ap-northeast-1_RoHXOwkFB”,“Arn”: “arn:aws:cognito-idp:ap-northeast-1:365487138721:userpool/ap-northeast-1_RoHXOwkFB”{“UserPoolClient”: {“UserPoolId”: “ap-northeast-1_RoHXOwkFB”,“ClientName”: “MysfitsUserPoolClient”,“ClientId”: “71gov86tiiphs9amjmd6kjopje”,“LastModifiedDate”: “2020-09-20T09:36:05.872000+09:00”,“CreationDate”: “2020-09-20T09:36:05.872000+09:00”,“RefreshTokenValidity”: 30,“AllowedOAuthFlowsUserPoolClient”: false }}### REST APIとAmazon API Gatewayの設定NLBの前にAmazon API Gatewayをはさんで、GatewayがCognitoを利用するようにする。またGatewayがNLBとプライベートで疎通するように、API Gateway VPCリンクも必要となる。

まずaws apigateway create-vpc-linkコマンドでNLBへのVPCリンクを作成。