🧪

【Python+heroku】Python入れてない状態からherokuで何か表示するまで(後編)

2022/01/24に公開

この記事は、2022.01.22-01.30 の期間で開催中の 「技術書典 12」 での新刊
ShotGrid Tips本の三冊目 「ShotGridチョットデキル」 の補足記事です。

https://techbookfest.org/event/tbf12/market

https://techbookfest.org/product/5296800539869184

「APIを使った定期処理」 P.11 の内容を補足します。元記事はQiitaにて2016年2月2日に公開したものです。


これはなに?

こちらの続きです

【Python+heroku】Python入れてない状態からherokuで何か表示するまで(前編)
https://zenn.dev/it_ks/articles/ba346db1fec156

ここまでで、heroku上にデプロイしてサンプルのまま動かしました。

heroku update

herokuインストール後、heroku自体のupdateが来てないか確認するのを忘れてました。
定番ですよね、やっとくといいですよね。

heroku update

>heroku update
Updating plugins... done. Updated 1 package.
heroku-cli: Updating... done.

更新があったようで、アップデートされました。

virtualenv

つくる

virtualenv venv-name

切り替えて使う当座の環境設定を構築してくれます。
venv-nameの とこが環境名。お好みの名前をつけて実行してください。
ここではオーソドックスに、「venv」という名前でつくります。

>virtualenv venv
New python executable in venv\Scripts\python.exe
Installing setuptools, pip, wheel...done.

すると、いまは C:\Users\(中略)\python-getting-started に居るわけですが、その直下にvenvっていうフォルダが作られます。
その中にはPythonもろもろ(40MBほど)がおさめられていて、これが汚していい環境一式ということになります。

有効にする。

activate.batってのが用意されてるので、それを使います。
すると、プロンプト(コマンドライン入力待ちの先頭)に環境名がつくようになります。

>venv\Scripts\activate.bat
(venv) C:\Users\(中略)\python-getting-started>

以下、 (venv) > と省略することにします

Push local changes

イマココ

https://devcenter.heroku.com/articles/getting-started-with-python#push-local-changes

requirementsファイルからインストール

(venv) >pip install -r requirements.txt
Collecting dj-database-url==0.3.0 (from -r requirements.txt (line 1))
  Downloading dj_database_url-0.3.0-py2.py3-none-any.whl
Collecting Django==1.9.1 (from -r requirements.txt (line 2))
  Downloading Django-1.9.1-py2.py3-none-any.whl (6.6MB)
    100% |################################| 6.6MB 75kB/s
Collecting gunicorn==19.4.5 (from -r requirements.txt (line 3))
  Downloading gunicorn-19.4.5-py2.py3-none-any.whl (112kB)
    100% |################################| 114kB 1.7MB/s
Collecting psycopg2==2.6.1 (from -r requirements.txt (line 4))
  Downloading psycopg2-2.6.1-cp27-none-win32.whl (814kB)
    100% |################################| 815kB 487kB/s
Collecting whitenoise==2.0.6 (from -r requirements.txt (line 5))
  Downloading whitenoise-2.0.6-py2.py3-none-any.whl
Installing collected packages: dj-database-url, Django, gunicorn, psycopg2, whitenoise
Successfully installed Django-1.9.1 dj-database-url-0.3.0 gunicorn-19.4.5 psycopg2-2.6.1 whitenoise-2.0.6

(venv) >

requirements.txt編集

requests==2.9.1 を requirements.txt に追記せよ、とのことなので書き足して、
それから pip install -r requirements.txt します。

(venv) >pip install -r requirements.txt
Requirement already satisfied (use --upgrade to upgrade): dj-database-url==0.3.0 in c:\users\cat_high\documents\guncys\herokustudy\proj\testapp\python-getting-started\sgenv\lib\site-packages (from -r requirements.txt (line 1))
Requirement already satisfied (use --upgrade to upgrade): Django==1.9.1 in c:\users\cat_high\documents\guncys\herokustudy\proj\testapp\python-getting-started\sgenv\lib\site-packages (from -r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): gunicorn==19.4.5 in c:\users\cat_high\documents\guncys\herokustudy\proj\testapp\python-getting-started\sgenv\lib\site-packages (from -r requirements.txt (line 3))
Requirement already satisfied (use --upgrade to upgrade): psycopg2==2.6.1 in c:\users\cat_high\documents\guncys\herokustudy\proj\testapp\python-getting-started\sgenv\lib\site-packages (from -r requirements.txt (line 4))
Requirement already satisfied (use --upgrade to upgrade): whitenoise==2.0.6 in c:\users\cat_high\documents\guncys\herokustudy\proj\testapp\python-getting-started\sgenv\lib\site-packages (from -r requirements.txt (line 5))
Collecting requests==2.9.1 (from -r requirements.txt (line 6))
  Downloading requests-2.9.1-py2.py3-none-any.whl (501kB)
    100% |################################| 503kB 518kB/s
Installing collected packages: requests
Successfully installed requests-2.9.1

(venv) >

hello/views.py編集

指示に従って、views.pyの先頭に下記を追記し、さらに、index関数を改変します。

import requests

# Create your views here.
def index(request):
    # return HttpResponse('Hello from Python!')
    return render(request, 'index.html')

def index(request):
    r = requests.get('http://httpbin.org/status/418')
    print r.text
    return HttpResponse('<pre>' + r.text + '</pre>')

ローカルでテスト

index関数を書き換えたら、テスト。
winの場合は「heroku local -f Procfile.windows」、macOS/Linuxの場合は「heroku local」と書きますが、読み落としていて後者を実行しています(笑?)

(venv) >pip install -r requirements.txt
(venv) >heroku local
forego | starting web.1 on port 5000
web.1  | Traceback (most recent call last):

(venv) >

ローカル環境は http://localhost:5000 にアクセスすると確認できるとのこと。

heroku上のファイルへ反映

まだここ

https://devcenter.heroku.com/articles/getting-started-with-python#push-local-changes

git add

git add .

(すると

warning: LF will be replaced by CRLF in〜〜

The file will have its original line endings in your working directory.

改行コードについてのログがいっぱい返ってきました。省略)

git commit

(venv) >git commit -m "Demo"

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got '{user}@{machine}.(none)')

(venv) >

「Please tell me who you are.」……すいません。

(venv) >git config --global user.email "aiueo@gmail.com"
(venv) >git config --global user.name "heroku user name"

そして再度コミット。

git pushと確認

git push heroku master とあったので粛々と従います。
アップロードはそこそこ時間がかかります。2分くらい?(※回線による)

(venv) >git push heroku master
Counting objects: 5952, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4984/4984), done.
Writing objects: 100% (5952/5952), 7.32 MiB | 87.00 KiB/s, done.
Total 5952 (delta 1807), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Using set buildpack heroku/python
remote: -----> Python app detected
remote: -----> Installing dependencies with pip
remote:        Collecting requests==2.9.1 (from -r requirements.txt (line 6))
remote:        Downloading requests-2.9.1-py2.py3-none-any.whl (501kB)
remote:        Installing collected packages: requests
remote:        Successfully installed requests-2.9.1
remote:
remote: -----> Preparing static assets
remote:        Running collectstatic...
remote:        Post-processed 'admin/js/vendor/xregexp/LICENSE-XREGEXP.txt' as 'admin/js/vendor/xregexp/LICENSE-XREGEXP.d64cecf4f157.txt'
(中略)
remote:        Post-processed 'humans.txt' as 'humans.d41d8cd98f00.txt'
remote:        Post-processed 'lang-logo.png' as 'lang-logo.019c8743b7cf.png'
remote:        58 static files copied to '/app/staticfiles', 58 post-processed.
remote:
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing... done, 50.3MB
remote: -----> Launching...
remote:        Released v6
remote:        https://ancient-taiga-0000.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.
To https://git.heroku.com/ancient-taiga-0000.git
   fe7f948..8bba81f  master -> master

(venv) >

(venv) >heroku open で(ローカルじゃない方のherokuを)確認。

コンソール

イマココ

https://devcenter.heroku.com/articles/getting-started-with-python#start-a-console

Python

heroku run python manage.py shell

(venv) >heroku run python manage.py shell
Running python manage.py shell on ancient-taiga-0000... up, run.8091
Python 2.7.11 (default, Dec  7 2015, 21:16:24)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> dir()
['__builtins__']

対話できるようになりました。
通信してるためか、タイプするときのレスポンスは低下します。

閉じるときはこう▼

>>> exit()

bash

heroku run bash

(venv) >heroku run bash
Running bash on ancient-taiga-0000... up, run.5888
~ $ ls
app.json        hello      Procfile          README.md         runtime.txt
gettingstarted  manage.py  Procfile.windows  requirements.txt  staticfiles
~ $ exit
exit

(venv) >

表示内容を編集

ここからが本番です。
さきほど改変したindex関数ですが、

    return HttpResponse('<pre>' + r.text + '</pre>')

この部分が、indexにアクセスしたとき表示される内容になります。
HttpResponse()文字列を与えればいい わけです。

例えば

def index(request):
    return HttpResponse( str(dir()) )

みたいな。

add、commit、push

.pyを編集したら、add→commit→push

(venv) >git add .

(venv) >git commit -m "DemoDemo"
[master 986e6d1] DemoDemo
 1 file changed, 4 insertions(+)

(venv) >git push heroku master
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 365 bytes | 0 bytes/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Using set buildpack heroku/python
remote: -----> Python app detected
remote: -----> Installing dependencies with pip
remote:
remote: -----> Preparing static assets
remote:        Running collectstatic...
remote:        Post-processed 'admin/js/vendor/jquery/jquery.js' as 'admin/js/vendor/jquery/jquery.107fbe9555bf.js'
(中略)
remote:        Post-processed 'humans.txt' as 'humans.d41d8cd98f00.txt'
remote:        Post-processed 'lang-logo.png' as 'lang-logo.019c8743b7cf.png'
remote:        58 static files copied to '/app/staticfiles', 58 post-processed.
remote:
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing... done, 50.3MB
remote: -----> Launching...
remote:        Released v8
remote:        https://ancient-taiga-0000.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/ancient-taiga-0000.git
   8bba81f..986e6d1  master -> master

(venv) >

結果:

index以外を追加

index関数は https://ancient-taiga-0000.herokuapp.com/ にアクセスしたときに呼ばれるわけですが、では例えば https://中略/test みたいな感じでアクセスできるようにするには。

関数追加

indexと同様の、return HttpResponse()な関数を追加します。
ここでは「test」関数を用意しました。

def test(request):
    return HttpResponse( '<strong>test view !!</strong>' )

urls.py編集

view.py とともに、 gettingstarted フォルダ直下にある urls.py も編集すればよいようです。
github上ではこれです。

https://github.com/heroku/python-getting-started/blob/master/gettingstarted/urls.py

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'gettingstarted.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^$', hello.views.index, name='index'),
    url(r'^db', hello.views.db, name='db'),
    url(r'^admin/', include(admin.site.urls)),
)

(▲)こういう部分があるので、こういう感じで追記してみました▼

    url(r'^test', hello.views.test, name='test'),

これで、何か表示するという目標を達しました、お疲れ様でした。

まとめ

前後編に渡って長かったけど大したことはやってません。

  • 後半は主に以下
    • views.pyに、表示したい処理を記載
    • urls.pyに登録
  • もとドキュメントにある「env」「postgrqsl」は飛ばしており、言及していません。

最後の test view ではstrongタグを使っているように、HTML文字列を用意して上げればよさそうです。
あとはその前に外部サービスとかと通信するなんか処理を書いておいて、それを整形して HttpResponse 関数に渡してあげる感じで行けそうです。

ということで 外部のAPIとか をあれこれして遊びたいですね。
冒頭で「ShotGrid本の補足」とあるように、ここでの 外部のAPI とは ShotGrid Python API を想定しています。

参考

無料枠内でのHerokuの準備とデプロイ(Mac 10 + Rails 4.2 + MySQL 5.6)
http://ruby-rails.hatenadiary.com/entry/20150314/1426332751


技術書典 12 は1月30日まで開催中です!
オンラインマーケットの当サークルのページはこちら。

https://techbookfest.org/organization/4820477751066624

Discussion