THUMBS SHIFT→

このブログは主に親指シフトを用いて書かれています

VS Code Server for WSL closed unexpectedly. Check WSL terminal for more details. というエラーが出る。

vscode+wsl2でモダン開発しよwってなったけどエラー出た。 ggるとPATHの設定だったり、proxyだったりがでてくるけどこれはWSL2になって改善されたっぽい(?)

PS > wsl
$: cd
~$: ls -a ←これで.vscode-server/がでてくるはず
~$: mv .vscode-server/ vscodeserver.backup
~$: code .

vscode-serverが再設定されるので治った。.backupつけた奴は様子見て消していいんじゃないでしょうか。

AVIOT TE-D01g のペアリング方法

左右分離式なので、結構ペアリングが上手くいかなかったりしてめんどいので、うまくいく経験的なやり方を書きます。

  1. 親機からペアリング解除し、イヤホンと親機の電源を切る(二回効果音が鳴るまでボタン長押しで電源off)
  2. イヤホンを左右ともペアリング状態にする(3回なるまで長押しでペアリング状態)
  3. 両方ともペアリングする。(説明書には片方でいいと書いてあったはず)

これが一番安定する気がします。

ちなみに再ペアリングすると、同じデバイスでも2デバイス扱いになるので、最後から3回目につなげたデバイスがイヤホンのメモリから削除されます。

片方だけペアリングしてもうまくいかないのはなぜ~~~~。

追記

両方電源ON→片方だけペアリング でも上手くいくことが最近判明しました。よかったですね。

Windows 10 EducationでMicrosoft Storeを利用する

大学配布のwinライセンスを使っているのでEducationになっているのですが、大学側で一部の利用が制限されている(?)ようで、レポート中でもwindows updateで強制再起動させられたりしています。

中でも一番困ったのが、Microsoft Storeが使えないことで、待ちに待ったWSL2とwindows terminalを入れられないというもどかしい思いをしていました。調べてみると一応解決したのでのせておきます。これがほかの人の環境でも有効なのかはわかんないです。

docs.microsoft.com

ここを見ましょう。 簡単に言うと、

  1. https://educationstore.microsoft.com/ja-jp/storeに行く。
  2. 学校のために購入タブからアプリを検索。(Ubuntuなど)
  3. アプリの入手をクリック
  4. 「インベントリに追加されました」と出るので、インストールをクリック
  5. Microsoft Storeを開く」をクリック

でできると思います。

注意として、microsoft storeのアカウントなのですが、これは自分のアカウントではなく、大学や会社など、組織のアカウントじゃないとだめです。大学の場合はwinのライセンスもらうときとかに配布されるんじゃないかなと思います。忘れたら・・・うん。

Django+React+GraphQLでSPAを作ってみた感想

Django+React+GraphQLでSPA(なお1ページのみ)を作ってみた感想を書いていきます。なお、趣味グラマーなので仕事で使う観点では見ていません。あと認証処理も実装してないです。

今回の構成

サーバーはHerokuをつかいました。フロントエンドとバックエンドでサーバーを分けます。最初は一緒のサーバーから配信しようとしたんですけど、ルーティングが(ReactのルーティングとDjangoのが混ざって)めんどいので止めました。

使ったライブラリ

  • バックエンド: Django, graphene-django
  • フロントエンド: React, Apollo, (Typescript)

大まかな手順

リポジトリはここ

フロントエンド github.com

バックエンド github.com

つくったのはこれ

https://ararkblog.herokuapp.com/

良さみ

Pythonが便利

まじで声を大にして言いたいんですけど、JSのデータ操作辛すぎる!!!!。特にArrayお前だよ。意味分からん仕様しかないのでPythonを使うと感謝で泣ける。

データ操作が楽

Djangoのモデルが強力なので簡単にGraphQLのレスポンスを書ける。まじで軽く調べてみた感じ、Node系のwebフレームワークはDB操作ほとんど自分でやらなきゃいけない印象があるのでこの点は良い。

graphene-djangoに乗っかれば簡単にページネーションを実装できる。

graphiQLが強い

ブラウザ上でGraphQLのクエリを書いて実行できるgraphiQLっていうのがgraphene-djangoに同梱されてるんですけど、これが便利。簡単なテストをすぐ書ける。

まぁ多分graphiQLは他のツールでも使えると思いますが。

Djangoが管理画面を生成してくれる

Djangoがadminサイトを自動生成してくれるので、データ見てみたり、テストデータ適当に作ったりするのに便利です。他のフレームワークにもあるかどうかはわからない。無い印象。

つらみ

Pythonが動的型

最初Pythonやってた時は、動的型付けサイコー!って感じだったけど、Typescript触ってからは静的型付けサイコー!になったのでPython辛い。補完効かないのが一番つらい。mypy早く進化してくれ・・・。mypyがTypescript並になったらほんとに最強。

あとDjangoの慣習として、モジュールとかメソッドを文字列で指定して、ランタイムで動的に解決するってのがある*1。これをやられるとデプロイはできるけど特定のアクションを行って初めてエラーが出ることがあるので辛い。

文字列じゃなくて直接オブジェクトを指定するようになったりしないのかな?結構冗長になるけど。

ルーティングが辛い

上でもちょっと書いたけど、DjangoでReactRouterとか使おうとすると、DjangoのURLとSPAのURLが衝突するのでめんどくさい。/adminがDjangoのかSPAのURLなのか、判定が面倒くさい。

今回はDjangoとReactでサーバーを分けた。ホントは一緒のサーバーから配信したいけど、SPAのお作法的にはどうなんだろう。あんまりこれについて書いてある資料がみつからなかった。

これはNode系のフレームワークだと解決するのかな?未調査。

使わない機能がおおい

まぁこれはつらみではないけど、テンプレートとビューを使ってないので、大雑把に言って2/3の機能を使ってない。できればミニマムにいきたい。

Pythonの環境構築のベストプラクティスがない

Nodeの環境構築はyarnかnpmを使って簡単にできるけど、PythonはPipenvが死んだせいで戦国時代になりつつある。早く統一されてくれ・・・

結論

バックエンドをNodeにしてもDjangoにしても結局辛みはあるので使いやすい方でやろう。

*1:include("hoge.urls")とか、MIDLLEWARE=["hoge.middleware"]みたいな

Djangoの設定のベタープラクティス

Djangoをデプロイする時の設定です。ベストプラクティスじゃなくて(そのままよりは)ベタープラクティスです

絶対に漏れ、抜けがあるので参考程度に見てください。公式を見るのが最も安全です。

settings.pyの分割

Djangoの本番/開発設定を切り分けるにはsettings.pyを開発用、本番用に分割するのが良いようです。実際DjangoCMSであるWagtailもそのような構成になっています。

普通にDjangoでプロジェクトを作ると、

$ django-admin startproject myprj
$ tree myprj

myprj/
├── manage.py
└── myprj
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

となりますが、Wagtailでは

$ wagtail start myprj
$ tree myprj
myprj/
├── manage.py
├── myprj/
│   ├── __init__.py
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── dev.py
│   │   └── production.py
│   ├── urls.py
│   └── wsgi.py

というように、共通の設定(base.py)を用意して、開発用(dev.py)と本番用(production.py)で設定を切り替えています。

そもそもなんで開発/本番で設定を切り替えたいかというと、

  • 本番ではDEBUG=Falseにする
  • SECRET_KEYを隠したい
  • ALLOWED_HOSTSを設定する

など、開発/本番で違う点があるためです。

settingsの中身

具体的に、dev.pyは以下のようになっています。

from .base import *

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'o4ei=g0^4cu88sw$@rwuy*gh!4lu7ex74#0t!h^0=fy2k$4-(2'

# SECURITY WARNING: define the correct hosts in production!
ALLOWED_HOSTS = ['*'] 

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'


# ここはよくわかんない。ローカル専用の設定かな?
try:
    from .local import *
except ImportError:
    pass

前述したとおり DEBUG=Trueなのと、ALLOWED_HOSTS=['*']です。 それにSECRET_KEYが直書きですね。

コメントにSECURITY_WARNINGとあるように、この設定は本番で使ってはいけません。また、SECRET_KEYを公にしてもいけません。もしGithubなどに公開してしまったら、別の値に変えた上で、dev.pyをリポジトリから消しましょう*1

ちなみにdev.pyのファイル名についてですが、ここにあるように、local_settings.pyとするのが一般的なようです。

つぎにproduction.pyです

from .base import *

DEBUG = False

try:
    from .local import *
except ImportError:
    pass

これだけ。もはや何もかいてないです。ちゃんと自分で設定しろということでしょう。

  • DEBUG=False
  • SECRET_KEY
  • DATABASE
  • ALLOWED_HOSTS
  • STATIC_ROOT
  • STATIC_URL

とかを設定すれば動くはずです。多分。

なお、Herokuにデプロイする時はdjango-herokuがよしなにやってくれますが、動作を知りたい人は以前の記事で書いたので読んでみてください。

arark.hatenadiary.jp

settingsを使うには

多分分割しただけだとpython manage.py <command>したときにファイルが見つかんないよ的なエラーが出るとおもいます。

manage.pyを以下のように変えてください。

# もともとこうなっているはずなので
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myprj.settings')

# このように設定ファイルの相対パスを指定する
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myprj.settings.dev")

dev/productionはやはり開発/本番で変えるはずなので、try-catchで、dev.pyがあればそっちを使うなどのように条件分岐させてみてください。

ちなみにwsgi.pyやasgi.pyなども同じように設定する必要があります。

*1:それがセキュリティ的に正しいのかはわかりませんが...

Folding@homeに参加しました。手順とトラブルシューティング。

Folding@home(fah)に参加しました。化石と化していた1050tiを使っています。

Folding@homeとは、タンパク質構造予測に必要な計算処理を、世界中の有志による分散コンピューティングで推進するプロジェクトです。 10年以上昔の話になりますが、PlayStation 3を活用したプロジェクトを覚えている方も多いかと思います。

Folding@homeを通じてCOVID-19治療薬の発見に貢献します - Cybozu Inside Out | サイボウズエンジニアのブログ

参加方法

僕はubuntuを使っているので、MacWindowsはあんまりわかんないです。多分インストールして、Foldで出来ると思います。

  1. ここから自分にあったインストーラーをDLする。
  2. Linux系は最低限、fahclientとfahcontrolをDLする。fahviewerはなくても良い。(多分)
  3. statusタブを開いて、Foldをクリックする。

FAQ

client, control, viewerの違いはなんですか?

それぞれが左のソフトウェアに依存しています(多分)。clientがコアソフトウェアで、controlが制御用、viewerでこんなのが見れます。 f:id:arark:20200328194236p:plain

GPUが使われないのですが?

まずドライバをインストールしましょう。

次に

sudo apt install ocl-icd-opencl-dev

してください。

そして、 clientを起動->configure->Expert->Extra Client Optionsの、gpuがfalseになっているならtrueにする->再起動 をやってください。

これでGPUを使ってFoldできるならOK。出来ないならconfigure -> Slots -> Folding Slots-> 追加 ->gpuを試してみてください。

これでも出来ないならわからないです...

GPUのステータスを見たい

nvidia-smi -l 3600

で1時間ごとに使用率とか、温度とかが見れます。

Foldが始まりません

結構中央サーバーにアクセスが集中しているようで、必要なデータをDLするまで時間がかかります。放置してると始まるかも。

ERROR:WU01:FS01:Exception: Could not get an assignmentってエラーがでたりします。

何を計算しているんですか?

解決できません!

公式フォーラムに行きましょう。

ちなみに、

EFLOPSレベルまでいったそうです。

ReactをHerokuに秒速でデプロイしたい

create-react-appで作ったプロジェクトに限った話です!!!!!!!

github.com

ここに書いてあるまんまですが、

APP_NAME=すごいアプリの名前
npx create-react-app $APP_NAME
cd $APP_NAME
heroku create $APP_NAME --buildpack mars/create-react-app
git push heroku master
heroku open

--buildpack mars/create-react-appが一番大事なところなので忘れないように。ちなみに既にあるHerokuアプリでcreate-react-appを使いたい時は、

heroku buildpacks:set mars/create-react-app

です*1

django-herokuは何をやっているのか

django-herokuに頼らず自分で設定していきたいので、まずはdjango-herokuが何をやっているか確認していきます。

github.com

環境変数という語がでてきますが、これはherokuのダッシュボードもしくはCLIから割り当てられる変数で、(おそらく)セキュアです。os.environ[<key>]で取得できます。

49行目 にsettings関数が有りますね。この中を読んでいけばよさそうです。

まず引数ですが、configにはlocals()が渡されるので、つまりはsettings.pyの名前空間です。

53行目からはデータベースの設定のようです。

loggerを飛ばして見ていくと、75行目で大事な設定をしているのがわかります。

 config['DATABASES']['default'] = dj_database_url.config(conn_max_age=conn_max_age, ssl_require=True)

ここでdj_database_url.configという関数がでてきますが、これは環境変数の$DATABASE_URLをURLとか、パスワードとかの部分に分解して、djangoの設定に合うようにパースしてくれています。

これでデータベースは終わりです。

次に92行目からstaticfileの設定をしているようです。

95行目からは以下のようなコードです。

        config['STATIC_ROOT'] = os.path.join(config['BASE_DIR'], 'staticfiles')
        config['STATIC_URL'] = '/static/'


        # Ensure STATIC_ROOT exists.
        os.makedirs(config['STATIC_ROOT'], exist_ok=True)


        # Insert Whitenoise Middleware.
        try:
            config['MIDDLEWARE_CLASSES'] = tuple(['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE_CLASSES']))
        except KeyError:
            config['MIDDLEWARE'] = tuple(['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE']))


        # Enable GZip.
        config['STATICFILES_STORAGE'] = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

STATIC_ROOTとSTATIC_URLの設定をして、STATIC_ROOTのフォルダを作っていますね。

そのあとwhitenoise*1をmiddlewareに追加して、STATICFILES_STORAGEもwhitenoiseのものに差し替えています。

110行目からはALLOWED_HOSTSです。

    if allowed_hosts:
        logger.info('Applying Heroku ALLOWED_HOSTS configuration to Django settings.')
        config['ALLOWED_HOSTS'] = ['*']

あーよくない。ALLOWED_HOSTS=['*']にしているのでよくないです。なにが良くないのかはわかんないです。

テスト環境ならこれでも良いでしょうが、本番の場合はちゃんとホストするアドレスを指定しておきたいですね。

114行目からはロガーの設定なので割愛。

151行目以下でSECRET_KEYです。

    if secret_key:
        if 'SECRET_KEY' in os.environ:
            logger.info('Adding $SECRET_KEY to SECRET_KEY Django setting.')
            # Set the Django setting from the environment variable.
            config['SECRET_KEY'] = os.environ['SECRET_KEY']

環境変数から取ってきたSECRET_KEYをconfigに割り当てています。間違ってもSECRET_KEYを公開しないようにしましょう。

これをsettings.pyに持ってくればherokuにデプロイできます。

まとめると

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MIDDLEWARE = [
    # ...
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ...
]


DATABASES = {
    'default': dj_database_url.config(conn_max_age=CONN_MAX_AGE, ssl_require=True)
}

SECRET_KEY = os.environ.get("SECRET_KEY")

のようになります。whitenoiseのインストールや、環境変数の割当を忘れないでください。

*1:nginxみたいなもの。静的ファイルを配信する。djangoが静的ファイルを配信するより高速

最近やったこと

結構ネタバレがある

読んだ本と見た映画

kindleでハヤカワセールやってるのでSFを読んでる。kindleやばい。いつでも読めるのでいつでも読むことが出来る。

夏への扉

夏への扉

猫の描写が良かった。飼ったこと無いけどあるある〜〜〜〜。てなった。

典型的なタイムトラベル物で、最後に伏線を全部回収していくのはやはり爽快。最後がハッピーエンドなので良い。頑張った後に金と女に恵まれる話っていいよね。

序盤はコールドスリープしか出てこなかったのでどうなるんだろうな〜と思ってたら途中からタイムマシンが出てきた。いやそれ最初からコールドスリープいらなかったのでは。

古典SFあるあるだけど、記述が冗長。刊行当初なら新鮮味があるだろう描写も、もはや現実の方が追い越しているので目新しさはない。

思弁系か娯楽系かでいうと圧倒的に娯楽系だったのでよみやすかった。

アメリカにアンクル・サムってふりがな振ってあるの格好良かったのでどこかで使っていきたい。

ソラリス (ハヤカワ文庫SF)

ソラリス (ハヤカワ文庫SF)

夏への扉と真反対の思弁系。最初の、お客さんの正体がわかるまではホラーとしてめちゃめちゃ楽しかった。わかってからは一気にSpeculative Fictionと化した。

ソラリス学はまぁ冗長だけど必要ではあると思う。あれのおかげでソラリスの特異性が強調される。

この本は様々な読み方をすることが出来る傑作SFというのが一般的な評価らしい。円城塔のいうところの、全てを説明しうるがゆえに何も説明できない概念というのを絡めてなにかもっともらしく論評しようとしたけどどうにもならなかったので辞めた。

スナウトとサルトリウスのお客さんは誰だったのかな。スナウトは動物っぽいと思う。

解説がちゃんと解説してて本当に良かった。解説とタイトルをつけてポエム書いてる著者まじで辞めてくれ。

帰ってきたヒトラー(字幕版)

帰ってきたヒトラー(字幕版)

  • 発売日: 2016/12/23
  • メディア: Prime Video

衝動的に見てみた。勿論原典ではないけど、再現されたヒトラーを見ていて、やっぱ演説が上手いんだなーとか思った。

序盤はタダのコメディで、後半にかけて雲行きが怪しくなっていくという展開も好き。

作中のヒトラー自身は何ら具体的な計画を語ってはいないけど、あまりに演説が上手いので自分の意見を代弁してくれている気がしてきた。

民主主義は国民の不断の努力によって維持されていかなければ行けないんだなぁというお気持ち。

本を読むのは良いけど、構造的に展開を把握できてないよなぁと思ったので読んだ。面白さを作るにはどんでん返しが必須というのは納得。あとは主人公の設定の仕方とか、敵の作り方とか。

純文学とか思弁SFとか、この本の解説から逸脱してるようなのもよくあるが、そういう小説を書くのはめちゃめちゃ難しいだろうな。

確定申告で悩んだので。街には沢山の店があるから開業は簡単そうに思ってたけど、実際は複雑だとわかった。あんなに店があることが信じられない。あと渋谷でどうやってテナント料払ってるのかわからない店だらけなの謎すぎる。

FGOでよく出てくるから読んだらいきなりアイアイエーイベ始まってびっくりした。読めば読むほど神が人間の味方だったことなんて一度もありませんよという気持ちになる。狂ってる?それ誉め言葉ね。

イアソンってすごい人なんだなとか、ヘラクレスは世界一強いんだから!とか、ゼウスカスすぎやろとか思うところが多い。あとはケルト神話北欧神話と日本の偉人とアーサー王伝説とインドと中国とその他諸々の物語を読まなきゃいけない......

ちなみにkindleで読んだけど固定レイアウトだったのが辛かった。

やってること

  • バイトを始めて病んでる
  • django+react+graphQLでSPA作ろうと思ってるけど、ルーティングとかデプロイとかセキュリティで詰まってる。
  • 運転の練習をしてる

poetryでnpm runしたいならtasks.jsonを使えばいいじゃない

pipenvは死んだからpoetryを使おうという記事を先日かいたけど、どうにもpoetryはpipenv runとか、npm runの代替となる機能がないらしい。 poetry runはあるけど、後ろのコマンドを全部手入力しなきゃいけなくて、poetry run <ユーザー定義スクリプト>はできない。

pyprojectにscriptsという設定があるけど、これはパッケージングのときに外部に提供するコマンドを指定する所らしくて、setup.pyentry_point=[console_scripts]みたいな使い方しかできないらしい。

実際、pyproject.scriptsにはpythonスクリプトしか指定できない。echoとかcdとか使えない。ロードマップを見ても、追加されそうな気配はない。

じゃあスクリプトを自作してしまおうというのが今回の主旨。前置きが長くなったけど、そんなに大したものではない。ツールはVSCodeのタスクランナーを使う。

VSCodeを開いて、Ctrl + Shift + pで設定を開く->Configure Taskで.vscode/tasks.jsonが作られる(多分)。

はじめに自分のtasks.jsonを載せておく。

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "runserver",
      "type": "shell",
      "command": "poetry run python ${cwd}/server/manage.py runserver",
      "presentation": {
        "reveal": "silent"
      }
    },
    {
      "label": "makemigrations",
      "type": "shell",
      "command": "poetry run python ${cwd}/server/manage.py makemigrations"
    },
    {
      "label": "migrate",
      "type": "shell",
      "command": "poetry run python ${cwd}/server/manage.py migrate",
      "dependsOn": ["makemigrations"]
    }
  ]
}

必須なのがlabel, type, commandで、他のはなくても良い。まぁ見ればわかると思うので詳しくはドキュメントを見てください。

今はDjangoの開発をしてるから、manage.py 関連しか無い。manage.pyは補完が効かないからまじで便利。

他にも便利機能としては${cwd}でルートディレクトリが取得出来る。他にも色々変数がある cwdだからcdしたら値変わるんじゃねとか思ったけどなんかルートディレクトリに固定されるみたい。動くからヨシ!

あとはdependsOnでタスクを連鎖させることができる。これでmakemigrations&migrateを一発で終わらせられる。

あとはこれをcommitすれば、vscodeならスクリプトを共有できる。