71436


## はじめに

現在、WerkzeugというPythonで書かれたユーティリティライブラリの[チュートリアル](https://werkzeug.palletsprojects.com/en/1.0.x/tutorial/)をやっているのですが、WSGIについて紹介された関数について理解仕切れていません。

## 分からないところ

[code]

    def application(environ, start_response):
    
        start_response('200 OK', [('Content-type', 'text/plain')])
    
        return ['Hello, world']
    
[/code]

上記のapplication関数は、下記3点からWSGIアプリケーションの要点を満たしている(by [WSGI -
Wikipedia](https://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface))ようなのですが、

  * WSGIアプリケーションは、callableオブジェクト (__call__が定義されたオブジェクト) として定義する（この例では application 関数）。このオブジェクトが呼び出される際、引数 environ としてCGIと同様の環境変数が渡され、引数 start_response として、ステータスコードとレスポンスヘッダを受け取るcallableオブジェクトが渡される。
  * start_response を呼び出して、ステータスコードとレスポンスヘッダを設定する。
  * WSGIアプリケーションの戻り値は、本文を生成するiteratableオブジェクトである必要がある。

ここで『`environ`がCGIと同様の環境変数である』、というのはどういうことなのでしょうか？CGIとはCommon Gateway
Interfaceのことだと思っているのですが、[Perlの$ENV{...}](https://perl.misty.ne.jp/21.html)のようにアクセス情報やブラウザ情報が入る何か...ということなのでしょうか？

またこの`environ`が関数の中で何か役割を果たしているようには見えないのですが`environ`はどう活きるのでしょうか？

質問が抽象的になってしまい申し訳ないのですが、どなたか教えていただけると幸いです。

## 追記

上記のapplicationをwsgiref.simple_serverの第三引数に入れて使われているのを確認したのですが、ここでもenvironが使われているようではありませんでした。  
※[公式ドキュメント/シンプルな WSGI HTTP
サーバ](https://docs.python.org/ja/3/library/wsgiref.html#module-
wsgiref.simple_server)  
※[技評/WSGIの概要](https://gihyo.jp/dev/feature/01/wsgi/0001)


CC BY-SA 4.0
2020-10-22T18:00:32.137
71434
2020-10-23T00:44:16.587
2020-10-22T18:18:54.937
40683
40683
question
python http
WSGIの例で出る関数で使われる引数environが何か知りたい


よくよく[Werkzeugのドキュメント](https://werkzeug.palletsprojects.com/en/1.0.x/tutorial/)を確認してみると、

"The environ contains all incoming information, the start_response function
can be used to indicate the start of the response."  
『environ には全ての受信情報が含まれており、start_response 関数はレスポンスの開始を示すために使用されます。』(拙訳)

と書いてありました。わかったようなわからないような感じはまだありますが...


CC BY-SA 4.0
2020-10-22T18:28:02.563
71435
2020-10-22T18:28:02.563
40683
71434
answer


質問を書いている時間で

[code]

    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/plain')])
        yield str(environ).encode()
    
[/code]

などとして動かしてみればすぐわかることです。

例えばuwsgiで動かせば

[code]

    {'REQUEST_METHOD': 'GET',
    'REQUEST_URI': '/',
    'PATH_INFO': '/',
    'QUERY_STRING': '',
    'SERVER_PROTOCOL': 'HTTP/1.1',
    'SCRIPT_NAME': '',
    'SERVER_NAME': 'xxxxxx',
    'SERVER_PORT': '9090',
    'UWSGI_ROUTER': 'http',
    'REMOTE_ADDR': '127.0.0.1',
    'REMOTE_PORT': '4075',
    'HTTP_HOST': 'localhost:9090',
    'HTTP_USER_AGENT': 'xxxxxx',
    'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'HTTP_ACCEPT_LANGUAGE': 'ja,en-US;q=0.7,en;q=0.3',
    'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
    'HTTP_CONNECTION': 'keep-alive',
    'HTTP_COOKIE': 'xxxxxx',
    'HTTP_UPGRADE_INSECURE_REQUESTS': '1',
    'HTTP_CACHE_CONTROL': 'max-age=0',
    'wsgi.input': <uwsgi._Input object at 0x10340e210>,
    'wsgi.file_wrapper': <built-in function uwsgi_sendfile>,
    'wsgi.version': (1, 0),
    'wsgi.errors': <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>,
    'wsgi.run_once': False,
    'wsgi.multithread': False,
    'wsgi.multiprocess': False,
    'wsgi.url_scheme': 'http',
    'uwsgi.version': b'2.0.19.1',
    'uwsgi.node': b'xxxxxx'}
    
[/code]

gunicornで動かせば

[code]

    {'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x10b881310>, 
    'wsgi.version': (1, 0), 
    'wsgi.multithread': False, 
    'wsgi.multiprocess': False, 
    'wsgi.run_once': False, 
    'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 
    'wsgi.input_terminated': True, 
    'SERVER_SOFTWARE': 'gunicorn/20.0.4', 
    'wsgi.input': <gunicorn.http.body.Body object at 0x10b8812d0>, 
    'gunicorn.socket': <socket.socket fd=9, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8000), raddr=('127.0.0.1', 60283)>, 
    'REQUEST_METHOD': 'GET', 
    'QUERY_STRING': '', 
    'RAW_URI': '/', 
    'SERVER_PROTOCOL': 'HTTP/1.1', 
    'HTTP_HOST': 'localhost:8000', 
    'HTTP_USER_AGENT': 'xxxxxx', 
    'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 
    'HTTP_ACCEPT_LANGUAGE': 'ja,en-US;q=0.7,en;q=0.3', 
    'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 
    'HTTP_CONNECTION': 'keep-alive', 
    'HTTP_COOKIE': 'xxxxxx, 
    'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 
    'HTTP_CACHE_CONTROL': 'max-age=0', 
    'wsgi.url_scheme': 'http', 
    'REMOTE_ADDR': '127.0.0.1', 
    'REMOTE_PORT': '60283', 
    'SERVER_NAME': '127.0.0.1', 
    'SERVER_PORT': '8000', 
    'PATH_INFO': '/', 
    'SCRIPT_NAME': ''}
    
[/code]

と出ます。  
（読みやすいように改行して不要な情報を置き換えてます）

どうやって起動されているか? どうやって呼び出されたか? 呼び出されたアプリケーションはどこから情報を得てどこに情報を渡せばいいか? といった情報を
**すべてひっくるめて** 環境（environment)と呼んでいると分かると思います。

このうちのいくつかはアプリケーションを書く人が使うかもしれない情報で、いくつかはWSGIアプリケーションコンテナが必要としているから保管してある情報です。

逆に言うと、それらを区別することなく一つの辞書にまとめて入れているから、環境というふわっとした言葉を選ばざるをえないのかな、と感じます。

* * *

> またこのenvironが関数の中で何か役割を果たしているようには見えないのですが

"どんなリクエストが来ようとも **一切気にせず** 固定の結果を返すアプリケーション"なのだから当然です。


CC BY-SA 4.0
2020-10-23T00:44:16.587
71436
2020-10-23T00:44:16.587
12274
71434
answer