Tag Archive : Python

/ Python

ニームの書で使った道具

2018-12-12 | Final Fantasy XIV, Flask, halipe.co, JavaScript, Python, Responder | コメントはまだありません

そのうち使ってるツールを差し替えたりもするだろうから、いったん今のとこの技術スタック(っていうの?)をメモしておく。
基本的にはPython(Flask)以外はほぼぜんぶ初めて使うもので占められている。ふつうは知らないことを追加するのは+1にしなさいっていうんだけど、完全に無視した。のたうち回ったし、のたうち回っている。

ニームの書(halipe.co)

Backend

スクリプトはすべてPython。Flaskつかってて、Responderにリプレイスできるか試している。最初はElixirいくか!!とか息巻いてたが、API作るくらいのことで死にそうなのでやめた。
いまはGAEのFlexible環境にDockerコンテナ投げてAPIサーバが立ち上がっていて、ほかにはCloud Functionsで関数(これもPython)がいくつか。

そもそもはKubernetesに習熟したいという野望があってしこしこyaml書いてた。超楽しい。が、SSL証明書の取得と設定らへんで盛大にすっ転んだうえ、誤ったコンフィグを投げてはLet’s encryptにロックされて作業が止まるため、急遽GAEに逃げ込んだという次第。証明書やらドメインまわりやらが便利すぎてヨダレ出た。一方でデプロイ10分以上かかるのはちょっと辛い。
なんかStandard環境でもPython3使えるみたいなのを見かけたのでそっちに移す予定。jsonやyaml読んでjson吐くくらいしかしてないしょぼいAPIの為に毎月5000円払っている。しょぼいわ。
むろんそんだけの機能を、Kubernetesでクラスタあげようとしてたわけです。立ち上がってたら5000円どこじゃ済まないが、それはいいんだ。インフラ屋でもない人がこういうのの構築やるにはホビーくらいしかチャンスがない。
コマンド一個でPodが増えたり減ったりするのは、なんとも言えない愉しみがあった。あのPodやらService、むかしは物理サーバ一個一個でやってたんだぜまじかよってかんじ。

CI

リポジトリはBitbucket使っているので、マスタへのマージの際にBitbucket Pipelinesを起こし、Slackに通知するようにだけしている。
Python側だけテストが少し書いてあって、フックでテスト通すとこまでできた。これももちろん初めてだったので、動いたときはそれはもう大変に嬉しくて、ムダにPushした(程なく無料ビルド時間を使い切り動かなくなった)。
JS側がテスト書くまで至っておらず、まだ完成してない。Jestというのを見つけたので使ってみようと思っている。

DB

DBはCloud Firestoreをつかっている。ゼロの状態からNoSQLのDBつくんの初めてだった。リレーションとかあんま気にしないでいい単純なアプリなので、あんまり深い困りごとには遭遇してない。タグ検索とかの実装用にインデックスのテーブルこさえたりしたけど、テーブルそのものに張ってるindexつかうのとどっちがいいんだろうみたいな感じ。活用してる感はない。
更新情報とかはSpreadSheetに書き付けていて、反映用のスクリプト叩くとFirestoreにデータを放るという運用をやっている。一番最初はvueファイルにまるまる書き込んでたので、更新情報のっける程度の用事でデプロイが発生していた。

Frontend

TypeScript + Nuxt.js。どっちも使ったことないので採用。ホビーとはいえ無茶な挑戦だった。困ったときにTypeScript/Vue.js/Nuxt.jsいづれの問題なのかの切り分けすらできないような三下が、まるっきり全部わかんない状態で挑んだ。
作業の大半は調べ物の時間で、文字通りヨレヨレになっていた。
いっぽう尋常でない学びはあった。イベントハンドラって何?みたいな基礎部分への理解も危ういくらいの人だったんだが、なんとかなりつつある(まだ危うい)。
CSSまわりはBulmaを入れた。じつはCSSフレームワークの導入からやったのも初めて。
ほんと今まで何やって食ってたんですかねという感じなんだが、すでに動いてるプロジェクトに参加することが多いと下地はあらかた出来上がっていたりで、構築にはあんまり関与しないで済んじゃってたという背景がある。

ほか

手元でバッチやらを書く下地はJupyterNotebookを使うことがある。ド頭から動かさずに気になるとこだけ叩けるというのがことのほか便利で感動している。
表の操作はPandasとか使ってるけど、必要でというよりは使う理由になるので入れてるといった感じ。慣れておきたい。

地図をはじめ、さまざまな画像は基本的にFireworksでやっている。今となっては太古のアプリなんだろうか。あたしの用途ではこいつを超えるアプリケーションが地上にない。Vectorスイスイ書いてビットマップを切り取る切り抜くとかを、こやつだけが軽快にやってくれる。問題は古いのででかい画像に超弱い。もともとメモリの危ういソフトなんだがすぐ吹っ飛びそうになるのでおそるおそるやっている。横1900のPNGを9枚も食わすともう挙動不審になる。

ロゴのVectorを作るとかはIllustlatorをつかっている。これも昔々のやつだけど、あたしは線が書けてaiが書き出せたらいいので、それ以外のことでは全く用途がない(せいぜいトレースくらい)ので、たぶんもうこの先新しいIllustlatorを買う機会もあるまい。いまはそっち側で食べてるわけでもないし。
あ、名刺作るときは活躍してるんだった。赤作るときはYMを100にするだけじゃなくて黒10%入れろとか、ああいう細かい話がたまーに活きることがある。
オンデマンド機だと関係ないけれども。

ローカルのエラーをどう拾う?

2018-12-09 | halipe.co, Python | コメントはまだありません

サーバサイドはまだいいけど、ローカルでエラー出るじゃん。というかフロントヘビーな時代だから不具合ってどっちかというとブラウザに出るわけで、そんなんこっち預かり知らんからリロードしてよみたいになるじゃん。
まあ仕事ならそんくらい適当でもいい(よくない)んだけど、ニームの書はそうはいかんので。尻ふく人あたししかいないんだもん。
(うちとこの場合だとjson読んでjson吐くくらいのことしかしてないから、APIでエラー出るってケースがそもそもほぼない)

ない頭捻ってうんうん考えた挙げ句、バックエンドと同じ文脈に持ってけばいいじゃねえかとなった。
ためしにフロントでなんかエラー出るとするわ。FirebaseのAPIがあかんかったーとか、中身は何でもいい。んで出たらとりあえず可哀相ですねリロードしてねでいいんだけど、拾ったエラーはAPIでpostしとくと。もうただひたすら起こった事象だけでもpostして、投げられたエラーコードやメッセージはFirestoreに保存していくと。むろんjs自体がエラーで止まっちゃったらどうしようもないんだけど、やらかしそうなとこにtry-catch張ってけばいいんじゃろ。例外上がったら問題点をまとめてAPIに投げると、すくなくともユーザの側でなんの問題が起きたのか、わかるんじゃないかなと。
こういう対応に詳しい人がいたらまた別のことやるのかもわからん。ちょっとぼんやり生きすぎていて、この辺のノウハウが全然ない。

相変わらずにーむのしょをいじっています

2018-12-08 | Final Fantasy XIV, halipe.co | コメントはまだありません

WP5.0に上げたら編集画面がWordみたいになった。なんでこういう余計なことをするんだ。まあいい。
昨日今日あたりは、スマホでタグ付けらんなかったのを修理(というか回避というか)して、認証コケるやつの背景を調べて(まだ糸口つかめない)、あと運用周りの準備してた。
いままで500エラー出てもなんも気づかないとかだったので、とりあえず500とtracebackひっかけたらSlackに飛ぶようにして、少なくとも検知はできますよと。あと、ユーザ登録時に認証状態が半端になるようなところがあるので、そっちもイベントで引っ掛けて検知だけでもできるように。

仕事でやってるとテストだの運用だの監視だのってダルいんですけど、さすがに自分のサービスなんでモチベーションが違うよね。それでも昔ツール書いてたときって障害とかには無頓着だったんだけども。たぶんGCPとかにあらかたツール揃っていて、アクセス解析や障害検知のセットアップしなくて済んだのが大きい。
そう考えると昔の人は偉かったんだなあ。すっごい他人事なのは、当時はまるっぽ知らんぷりで人任せにしてたからです。

SQLAlchemyとSQLiteで日付を取り扱う

2014-06-28 | Python, SQLAlchemy | コメントはまだありません

あたくしの脳にぼんやりと刻まれている情報によれば、SQLiteは文字列と数値しか扱えないはず。
日付どうする。いやセンセ、日付ぐらいは扱ってくれてもいいのでは。
さておき、SQLAlchemyを通した場合に、なにか賢い仕組みがあるはず。

SQLAlchemyのマニュアルの当該ページには、

Date and Time Types

SQLite does not have built-in DATE, TIME, or DATETIME types, and pysqlite does not provide out of the box functionality for translating values between Python datetime objects and a SQLite-supported format. SQLAlchemy’s own DateTime and related types provide date formatting and parsing functionality when SQlite is used. The implementation classes are DATETIME, DATE and TIME. These types represent dates and times as ISO formatted strings, which also nicely support ordering. There’s no reliance on typical “libc” internals for these functions so historical dates are fully supported.

超訳:
SQLiteは日付型持ってない。SQLAlchemyが独自にこさえてる日付とかの型は、日付フォーマット+SQLiteで使った場合に動作するようになってる。その対象になってるのはDATETIME、DATEおよびTIMEだ。
これらを使う場合に限っては順番とかもちゃんと正しく動くし、ISOフォーマットされた文字列として日付と時刻を表現する。
で、こいつらはlibc内の関数に依存していないので、歴史的な日付が完全にサポートされている。

うわー自信ない。特に最後の一行。逆に読んでたらどうしよう。だって「libc非依存なのでヒストリカルデートが完全にサポートされてる」って、前後つながってる感がない。
だいたい、libcってなんだ。cのライブラリか。

ちょろっと見るとORACLE様の変なページが見つかり、「表 2–10 libc の日付と時間の処理関数」というところで以下の3つの関数の記述がある。

  • getdate() ユーザー形式の日付と時間を変換する
  • strftime() 日付と時間を文字列表現に変換する。
  • strptime() 日付と時間の変換

ははあ。こいつら完全にあたし見たことあるわ、phpで。phpのあの関数ってこいつらをラップしてたんだろか。
見てみる。
こんなページがあった。
PLEAC-PHP(http://pleac.sourceforge.net/pleac_php/datesandtimes.html)

これによると、phpはいろんな方法で日付のサポートをしていて、

  • UNIX/Cライブラリベース
    (localtime, gmtime, strftime, strptime, mktime, time, getdate, gettimeofday)
  • PHPのネイティブ関数(date,strtotime)
  • DateTimeクラスベース

日付の扱い方にこういう種類があるんだよ、とある。
phpのstrftimeとかははラッパーだったんだー、いやそういう感じのことなんだろうなとは思っていたがちゃんと理解した。
Library [libc]-based routinesってことは、Cのライブラリってのがlibcってことでいいんだな。なので、SQLAlchemy+SQLiteにおきましては、こいつらには関係ない作りになってます。ってことですね。
いやー勉強になりました。

Leap Motion with Python

2013-08-12 | LeapMotion, Python | コメントはまだありません

もーなんか、なんつうの、ほっといてもモチベーションがぐわーと上がるとかもないのんで、仕方ないので重い腰を上げることにするのよ。
なんで買った途端にモチベーション下がってんだ。

なんとなくPYTHONPATHを通してみる

結論から言うけどダメ。

>>> import Leap
Traceback (most recent call last):
File ““, line 1, in
File “C:\Program Files (x86)\Leap Motion\LeapSDK\lib\Leap.py”, line 31, in
LeapPython = swig_import_helper()
File “C:\Program Files (x86)\Leap Motion\LeapSDK\lib\Leap.py”, line 23, in swi
g_import_helper
import LeapPython
ImportError: DLL load failed: %1 は有効な Win32 アプリケーションではありません。

ああ。やる気なくなる。
いちいち説明するのもめんどくさいので、いきなりゴールにいきますね。

正解:全部同じディレクトリに放り込む

乱暴極まりない。なんだこれ。
あたしんちの場合ですと、site-packages下にleapというディレクトリを掘りまして、

C:/Python27/Lib/site-packages/leap
__init__.py #空ファイル作る
Leap.dll
Leap.lib
Leap.py
LeapCSharp.dll
Leapd.dll
Leapd.lib
LeapJava.dll
LeapPython.pyd
msvcp100.dll
msvcp100d.dll
msvcr100.dll
msvcr100d.dll

Leap.pyと、その下にあったx86もしくはx64の下をぜんぶおなじとこに散らかすことでセットアップ終わります。

>>> from leap import Leap
>>> Leap

ふー。
やっと取り掛かれるって寸法ですぜ。

さんざっぱらエラー吐かれている時に、

fp, pathname, description = imp.find_module(‘LeapPython’, [dirname(__file__)])

なんでここ探してんのかなーって気づく視点が必要でした。
まだまだPythonに慣れてない感じよ。

余談

PyPi探してみると、どーもleapって名前の技術かなんかがあるみたい。
ディレクトリ名はleapmotionとかにした方がいいのかもね。
あたしはそのままやるけどね。