Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

python - Heroku Flask Tutorial Procfile Meaning

In the heroku tutorial, there is a piece of code

hello.py

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

and a Procfile:

web: gunicorn hello:app --log-file=-

The part that's really confusing is the hello:app part; does hello refer to the hello() function or the hello.py script? Depending on the meaning of that, what does the whole Procfile statement mean?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

tl;dr: hello refers to hello.py and app refers to app = Flask(__name__)


The mentioned Heroku tutorial is no more available, however Gunicorn's doc gives a good minimal example :

Example with the test app:

def app(environ, start_response):
    """Simplest possible application object"""
    data = b'Hello, World!
'
    status = '200 OK'
    response_headers = [
        ('Content-type', 'text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])

You can now run the app with the following command:

$ gunicorn --workers=2 test:app


Let's try, my test-directory looks like this :

(.venv) 14:41 ~/testgunicorn % tree
.
├── requirements.txt
└── testpkg
    ├── __init__.py
    └── testfile.py

__init__.py :

from flask import Flask
from .testfile import app

testfile.py :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def app(environ, start_response):
    """Simplest possible application object"""
    data = b'Hello, World!
'
    status = '200 OK'
    response_headers = [
        ('Content-type', 'text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])

Wrong calling :

(.venv) 14:41 ~/testgunicorn % gunicorn testfile:app         
[2018-08-24 14:41:44 +0200] [27248] [INFO] Starting gunicorn 19.9.0
[2018-08-24 14:41:44 +0200] [27248] [INFO] Listening at: http://127.0.0.1:8000 (27248)
[2018-08-24 14:41:44 +0200] [27248] [INFO] Using worker: sync
[2018-08-24 14:41:44 +0200] [27251] [INFO] Booting worker with pid: 27251
[2018-08-24 14:41:44 +0200] [27251] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/workers/base.py", line 129, in init_process
    self.load_wsgi()
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/workers/base.py", line 138, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
    return self.load_wsgiapp()
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "~/testgunicorn/.venv/lib/python3.6/site-packages/gunicorn/util.py", line 350, in import_app
    __import__(module)
ModuleNotFoundError: No module named 'testfile'
[2018-08-24 14:41:44 +0200] [27251] [INFO] Worker exiting (pid: 27251)
[2018-08-24 14:41:44 +0200] [27248] [INFO] Shutting down: Master
[2018-08-24 14:41:44 +0200] [27248] [INFO] Reason: Worker failed to boot.
zsh: exit 3     gunicorn testfile:app    

Good callings :

(.venv) 14:43 ~/testgunicorn % gunicorn testpkg:app 
[2018-08-24 14:43:56 +0200] [27302] [INFO] Starting gunicorn 19.9.0
[2018-08-24 14:43:56 +0200] [27302] [INFO] Listening at: http://127.0.0.1:8000 (27302)
[2018-08-24 14:43:56 +0200] [27302] [INFO] Using worker: sync
[2018-08-24 14:43:56 +0200] [27305] [INFO] Booting worker with pid: 27305
^C
(…)

(.venv) 15:03 ~/testgunicorn % cd testpkg    
(.venv) 15:03 fred@susa ~/git/ocp7/testpkg % gunicorn testfile:app
[2018-08-24 15:03:22 +0200] [27494] [INFO] Starting gunicorn 19.9.0
[2018-08-24 15:03:22 +0200] [27494] [INFO] Listening at: http://127.0.0.1:8000 (27494)
[2018-08-24 15:03:22 +0200] [27494] [INFO] Using worker: sync
[2018-08-24 15:03:22 +0200] [27497] [INFO] Booting worker with pid: 27497
^C
(…)

Then for this Procfile :

web: gunicorn hello:app --log-file=-

Does hello refer to the hello() function or the hello.py script?

To the hello.py script

Depending on the meaning of that, what does the whole Procfile statement mean?

Heroku's Procfile format documentation says :

A Procfile declares its process types on individual lines, each with the following format:

<process type>: <command>

  • <process type> is an alphanumeric name for your command, such as web, worker, urgentworker, clock, and so on.
  • <command> indicates the command that every dyno of the process type should execute on startup, such as rake jobs:work.

The --logfile=- option seems to be deprecated, I did not find anything about it in documentation and if I use it I get this error :

(.venv) 15:34 ~/testgunicorn % heroku local web
[WARN] No ENV file found
15:34:30 web.1   |  usage: gunicorn [OPTIONS] [APP_MODULE]
15:34:30 web.1   |  gunicorn: error: unrecognized arguments: --logfile=-
15:34:30 web.1   Exited with exit code 2

According to this answer it was an option for logging in Heroku's stdout.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...