初心者向け Pythonanywhereを使ってみよう（2023/09/09色々追加あり）

## 目的
Pythonで書いたWebプログラムを簡単にインターネット環境で使えるようになる「Pythonanywhere」の使い方、主に自分が書いたコードをデプロイして公開するまでのやり方について自分のためのメモ書きとして残すことであります。そして多少なりとも初心者の「やってみたい！」という気持ちに向けて、未知の世界へトライする時に越えなけりゃならないなにがしかのハードルを少しでも低くすることができれば、同じ初心者としてうれしいです。
## 環境
Pythonanywhere上の環境は以下の通り

<ul>
<li>Python==3.8
<li>Django==3.2.3
</ul>
PythonanywhereはPythonのバージョン指定ができます。Djangoなど必要なライブラリはConsoleからバージョンを選択してinstallできます、ってかHerokuみたいなrequirements.txtが使えるかどうかよくわからんから、自分の環境で必要なライブラリを個別にinstallしとかなきゃなりません。（ゴニョゴニョすればrequirements.txtも使えるかもしれないけど、確認してません）

##「Pythonanywhere」というサービス

<a href="https://www.pythonanywhere.com/">Pythonanywhere -Host, run, and code Python in the cloud: PythonAnywhere</a>

Herokuと同じく無料で利用できますが、以下のような制限があります。
無料利用のBeginnerの場合（詳細はサイトの説明を読んで下さい）
<ul>
<li>同時利用できるアプリは１つのみ
<li>独自ドメインは取れません
<li>同時に使えるコンソールは２コまで
<li>CPU利用可能時間は100秒（直近24時間以内？）
<li>帯域は狭い（回線は細い、遅い）
<li>利用可能なストレージは512MB
<li>無料で使えるMySQLが提供される
<li>しばらく使わないとスリープ状態となる（次回起動に時間がかかる）
</ul>

MySQLの容量が利用可能なストレージに含まれるかどうかという内容については見つけることができませんでした。

## Pythonanywhereの登録とかは他の詳しいサイトを参照してね

Pythonanywhereサービスの細かい内容や登録方法などはググってみてください。

いろんなサイトに最初にTokenを取得しろと書いてありますが、これはサイトへの接続テストをするくらいで、実際のデプロイで使うことはありませんでした。でも取得せよと軒並み書いてあるのでとりあえずとっとく。

Djangoの環境設定（特にDEBUGモードの設定による振る舞いの違い）についても最低限の知識は事前にゲットしたうえでローカルで動くDjangoのソース群の準備は大前提です。

それからGithub経由で資源をアップロードするので、まずはそちらのアカウントを取得したのち資源をプッシュしておいてください。Githubがよくわからん人はそっちも先に調べててください。

ちらりとLinuxコマンドも使いますので、一番基本的なコマンドが書いてあるサイトを見つけておいてください。

サイトによっては「仮想環境を作って」などと書いてるけど、仮想環境を作らなくても動きます。設定項目が増えるので、めんどくさい人は仮想環境を作らなくても大丈夫（めんどくさいし、トラブった時の問題解決をシンプルにしたかったからワシは作らずにやりました）
![20210620071053.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/05012340-0ac6-af44-e1ab-5e8596704524.png)
Pythonanywhereのダッシュボード画面です。ここからいろんな機能に飛んだりできますね。
以下、「」で囲んでいるのはPythonanywhereが提供する機能名です。

ローカルのソースをアップロードする機能は提供されているし、gitコマンドも使えるはずなんだけど、バックアップの意味もあってソースは一度Githubへアップロードしました。

そのソースをアップロードするため「Console」でGithubのリポジトリをクローンします。

これについてはpythonanywhereというライブラリをインストールして、コマンドを叩けばいいと書いてあるサイトも多いんだが、ワシの場合はそれだとなんだかうまくいかなかったということもあって、素直にGithubからクローンしました。

そのまえに「Web」からダミーの環境をつくっておくと、後で出てくるWSGI configuration fileが自動的に作られるので、そいつを流用すればいいからその後の作業が楽になります。（ダミー環境の作り方についてはメモ取ってなかったので、自分で頑張ってやってみて下さい）

さてgit cloneは普通に実行すればオーケーです。
```
”git clone https://github.com/自分のユーザ名/リポジトリ名”　
```
(https://以降は開いている自分のリポジトリのURLをコピペしましょう）

2023/09/09追加）
最近、ひさびさにgit cloneをやってみたら、前と仕様が変わってました。
git cloneコマンドを打つとgithubのユーザ名入力のあとにパスワードの入力を求められますが、これはgithubログイン用ではなくて資源へのアクセス用の専用パスワードです。
それはpersonal access tokenの取得すると示される文字列で、標準で取得から30日間有効なtokenとなります。
取得方法はググって探してください。現在二種類の取得方法がありますが、私はpersonal access token(classic)で対象サービス全部選択（多分安全性という観点では適切ではないけど）でやってみたらうまくいきました。

https://capybara-notebook.com/github_accesstoken/


![20210620071629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/d54dbf78-3da6-e153-f7d1-5679dc397a24.png)
「Console」は画像の通り普通のBashなので怖がらずにコマンドを打っちゃってください。

git cloneを実行すると自分のPythonanywhereの環境にリポジトリ名が付けられたフォルダが作成され、その下に資源がアップロードされてます。Pythonanywhereでは「File」から対象のソースコードを選択すれば、画面上から直接修正もできます。なので、必要に応じてgitのcommitとかpushとか、Github側を修正したならば、pullとかを「Console」からいつも通りにやっちゃって下さい。
![20210620010647.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/ee8efc2a-6067-a2d5-0618-907b9c03b102.png)
「File」を開くと、自分の環境のディレクトリツリーを見ることができます。
今回はdockerで動かしてみた時のリポジトリをそのまま使いました。nginxという名前は、Webサーバにnginxを使ってたからわかりやすいと思って付けただけです。mysite/というのは、WSGIファイルの設定を楽にするためにPythonanywhereで作ったダミーのDjangoプロジェクトです。こいつは自分のソースで動き始めたら消してもオーケー。
![20210620010824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/33e3431e-2b28-66a3-7cd2-c28f07733467.png)

nginx/配下はこんなかんじ。ここにもテスト用やdocker用に作ったときの名残がたくさん残ってます。
Pythonnaywhereにソースをアップロードできたら、次にやるのがソースの保存場所の指定。「Web」にあるメニューからなので簡単だけど、パスの参照ができないからすべて手で登録する必要あり。
![20210620011121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/14537b7b-e2a8-3f15-b53a-cc4e23d9c2b3.png)

次に行うのが上の画面にある"WSGI.configuration file"という部分。リンクをクリックするとWSGIの設定ファイルが表示されるので修正しましょう。
WSGIについてはすでにダミーサービス用に作成されているので、そいつの中の二箇所を修正すればオーケー。
自分のプロジェクトが保存されているフォルダ名と、setting.pyがある場所を指定します。
WSGIとはなにか？と疑問に思った人は、自分でググってください。ワシも詳しいことは知らんから、ちょっとだけでもエラくなったらワシに教えて下さい。
![20210620011917.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/20d64ed0-4e7c-67d6-3887-f8e34d389c82.png)

修正は二箇所のみです。この時点でmysite/は不要なので削除しても問題ない（はず）
あとはmediaフォルダとかstaticフォルダとかを「Web」から必要に応じて指定してください。mediaやstaticフォルダの指定に合わせてsetting.pyも直す必要があるかと思ったけど、関係ないみたい（不確かな情報）です。そんなカンジなので、view.pyでダイレクトにパス指定などしている場合にはバグ発生となるかもしれませんので、テストはきっちりやるように。

で、setting.pyといえば接続を許可するURLやアドレスの指定が必要ですが、それについては

"ユーザ名.pythonanywhere.com"

と、サービスへアクセスするURLをそのまま指定すればオーケーです。

よくわからん人は、ダミーで作ったmysite/配下にあるsetting.pyのALLOWED_HOSTS行に書いてあるそのままをコピーすればオーケー。
![20210620012506.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/6f8407ca-68cc-35fc-ed58-32c39f267af4.png)

DEBUG = False にしとく。
ここまで準備したら「Console」からDjangoを初めて動かすときのおまじないであるマイグレーションを実行するんですが、python3 manage.py migrateはローカルと比べて処理時間がかかるので我慢して待ちましょう。またローカルのデーターベースで動かした実績がある資源をそのままアップしてmigrateしたときにエラーが表示される場合、migrateディレクトリに保存されているmigrate履歴ファイルを削除したりすればいいみたいですよ。（データベース初期化のときに限る）

もういっこDjangoの本番デプロイ時にやれと書いてあるstaticファイルを本番用指定フォルダにまとめるPython3 manage.py collectstaticなんですが、「Web」から実行環境に合わせてstatic/のパスを指定しておけば、実行しなくても動きました。(setting.pyのstatic指定が開発環境のままでも動いた理由はここらへんにあるかもしんない）
![20210620012634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/a7b41ed5-818f-acbe-e1b6-e2a1ccf510eb.png)

なにか修正したら緑のリロードボタンを押すのは必須
ここまでできればあとはリロードボタンを押して変更を反映させた後に、自分のサイトにアクセスしてみましょう。「Web」のConfiguration forの右側のリンクをクリックすると自分のサイトへ飛べます。

これでおしまい。うまくいくはず。エラー画面が出てきたら、それはなにかの設定がおかしいので、定番の手順どおりにsetting.pyのDEBUGをTrueにして、画面に表示されるエラーメッセージを見ながらぼちぼち直してゆきましょう。

特に書かなかったんですが、Djangoを始め必要なライブラリは個別に「Console」からインストールしなければならないっぽいです。（ワシの場合は色々やってたら勝手にインストールされたっぽいので、どこまでやるべきかがよくわからない）もし動かなかったらそっちも疑え。とりあえずインストールしてみろ。なおPythonanywhereではPython2も使えるっぽいので、PiPやPythonを使う場合にはバージョン３を明示して実行する必要があります（と思います）。例えばpip3 installとかpython3 manage.pyとか。

最初に書いたとおりデータベースは無料サービスとしてMySQLが使えますが（PostgreSQLは有料）、SQLite3でも問題なさげでした。Herokuの無料ユーザ環境では定期的にファイルが消されるらしいので、使うな（その代わり無料のPostgreSQLが使える）と言われてましたが、Pythonanywhereでは（３ヶ月程度過ぎると消されるみたいだけど）Herokuみたいにすぐに消えることはないみたいです（未確認事項）

それではみなさん、これからも楽しいPythonライフを！

2023/09/09追加）
pythonanywhereが提供するMySQLに接続するために試したことも書いてますので、参考までに。

https://qiita.com/tonytani37/items/3f751306bacd0ee7d4eb

ちなみにstaticやmediaをGoogle cloud strageにしてみましたが、ググって見つけた記事の内容をコピペしたら上手く行きました。事前にGoogle Cloud Platform側でアクセス許可用のjsonファイル取得も忘れずに。取得の仕方はググればわかります。

```
    STATIC_ROOT = 'https://storage.googleapis.com/自分がつくったバケット名を指定する/'
    STATIC_URL = 'https://storage.googleapis.com/自分がつくったバケット名を指定する/'
    MEDIA_URL = 'https://storage.googleapis.com/自分がつくったバケット名を指定する/'
    MEDIA_ROOT = 'https://storage.googleapis.com/自分がつくったバケット名を指定する/'

    GS_PROJECT_ID = '自分のプロジェクト名'
    GS_BUCKET_NAME = '自分がつくったバケット名'
    STATICFILES_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
    DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
    GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
        # 鍵ファイルのPATHを設定
        os.path.join(BASE_DIR, 'アカウント確認用のjsonファイル'), #この場合ルートに置いてることになってます。
    )
```
Google Cloud Platformアクセス用のDjango関連ライブラリのインストールも必要なので、たぶん

```
google-cloud-storage==x.x.x
django-cleanup==x.x.x
django-googledrive-storage==x.x.x
django-storages==x.x.x
```
コイツラあたりをrequirements.txtに書いといてDjangoその他必要なライブラリ群と一緒にインストールしちゃってください。(x.x.xはお好みのバージョンを指定）

ライブラリ群の一括インストールはおなじみrequirements.txtに書いとけばラクチンです。
```
pip3 install -r requirements.txt
```
pythonanywhereはpython3とそれ以前を区別してるっぽい気もするので、pip3としてインストールしたほうが無難な気がしました。



## 最後に言っときたかったこと
### 「オマエラ、実際に動かしてみたんか？」
初めてPythonanywhereを使ってみようと関連情報を検索したらたくさんのそれらしいサイトが見つかったから、そいつらを参考にしていじってみたんだがうまくいかん。なんでうまくいかんのじゃと人のせいにしながら軽く怒りつつ続けて色々と試してみた。すると見つかったそれらのサイトの記述には書いてることは同じで体裁だけが違うだけのものがたくさんあるのに気がついた。ってか、同じじゃん。その上「Githubにある自分のソースをデプロイするやり方」の説明で「これでデプロイ完了です」と書いているのに、そこに掲載されているデプロイが完了した「あなたの画面」は、Djangoでプロジェクト作成後に立ち上げみるテストサーバーの画面だったりするわけで、それは自分のサービスじゃないだろ？それはDjangoが出してるテスト用初期画面だろ？そんな程度で「これであなたのサービスが公開できる」とドヤ顔のサイトがたくさんあったのでガッカリする。

![20210620005318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/54b73a01-b4f0-7892-4045-f7ffb24273b7.png)
こいつはDjango-adminでプロジェクトを作成したあと、開発用サーバーを立ち上げるだけで出てくる画面ですから。自分が開発した画面じゃないですから。それをドヤ顔で「あなたの画面です！」なんて言っちゃだめでしょ。初心者が混乱するでしょ。
# オマエラ、実際に動かしてないだろ？他のサイトを見て、コピペしてエラそうにしてるだけだろ？！そんなの勉強しようとしているヒトタチのノイズになるだけだからやめろ。

現場からは以上です。