WSGI ditakrifkan dalam PEP 3333, yang saya menggalakkan anda membaca sebagai rujukan jika anda mahukan maklumat lanjut selepas intro cepat ini.
Artikel ini akan memperkenalkan anda kepada spesifikasi WSGI dari perspektif pemaju aplikasi, dan menunjukkan kepada anda bagaimana untuk bekerja secara langsung dengan WSGI untuk membuat aplikasi (jika anda inginkan).
aplikasi WSGI pertama anda
<span>def app(environ, start_fn): </span> start_fn<span>('200 OK', [('Content-Type', 'text/plain')]) </span> <span>return ["Hello World!\n"] </span>
Sekarang, anda harus sangat teruja. Hanya 3 baris untuk aplikasi yang sedang berjalan? Itu mestilah semacam rekod (sekatan PHP, kerana mod_php adalah penipuan). Saya yakin anda hanya perlu mengetahui lebih lanjut.
Jadi apakah bahagian -bahagian penting aplikasi WSGI?
Contohnya, dua contoh berikutnya bersamaan dengan yang pertama:
<span>def app(environ, start_fn): </span> start_fn<span>('200 OK', [('Content-Type', 'text/plain')]) </span> <span>return ["Hello World!\n"] </span>
<span>class app(object): </span> <span>def __init__(self, environ, start_fn): </span> self<span>.environ = environ </span> self<span>.start_fn = start_fn </span> <span>def __iter__(self): </span> self<span>.start_fn('200 OK', [('Content-Type', 'text/plain')]) </span> <span>yield "Hello World!\n" </span>
Anda mungkin sudah memikirkan cara anda boleh menggunakan maklumat ini, tetapi mungkin yang paling relevan adalah menulis middlewares.
middlewares adalah cara mudah untuk memperluaskan fungsi aplikasi WSGI. Oleh kerana anda hanya perlu memberikan yang boleh dipanggil, anda boleh membungkusnya dalam fungsi lain namun anda suka.
Sebagai contoh, katakan kita mahu memeriksa kandungan persekitaran. Kita boleh membuat middleware dengan mudah untuk melakukannya, seperti dalam contoh ini:
<span>class Application(object): </span> <span>def __call__(self, environ, start_fn): </span> start_fn<span>('200 OK', [('Content-Type', 'text/plain')]) </span> <span>yield "Hello World!\n" </span> app <span>= Application() </span>
di sini, log_environ adalah fungsi yang mengembalikan fungsi, yang cukup mencetak hujah persekitaran sebelum menangguhkan panggilan balik asal.
Kelebihan menulis middlewares dengan cara ini adalah bahawa middleware dan pengendali tidak perlu tahu atau peduli tentang satu sama lain. Anda boleh dengan mudah bolt log_environ ke aplikasi flask, sebagai contoh, kerana aplikasi flask adalah aplikasi wsgi.
Beberapa idea middleware berguna yang lain:
<span>import pprint </span> <span>def handler(environ, start_fn): </span> start_fn<span>('200 OK', [('Content-Type', 'text/plain')]) </span> <span>return ["Hello World!\n"] </span> <span>def log_environ(handler): </span> <span>def _inner(environ, start_fn): </span> pprint<span>.pprint(environ) </span> <span>return handler(environ, start_fn) </span> <span>return _inner </span> app <span>= log_environ(handler) </span>
Anda boleh menggunakan mengurangkan untuk memohon sekumpulan middleware sekaligus jika anda tidak mahu membuat piramid besar di bahagian bawah fail anda:
<span>import pprint </span> <span>def handle_error(handler): </span> <span>def _inner(environ, start_fn): </span> <span>try: </span> <span>return handler(environ, start_fn) </span> <span>except Exception as e: </span> <span>print e # Log error </span> start_fn<span>('500 Server Error', [('Content-Type', 'text/plain')]) </span> <span>return ['500 Server Error'] </span> <span>return _inner </span> <span>def wrap_query_params(handler): </span> <span>def _inner(environ, start_fn): </span> qs <span>= environ.get('QUERY_STRING') </span> environ<span>['QUERY_PARAMS'] = urlparse.parse_qs(qs) </span> <span>return handler(environ, start_fn) </span> <span>return _inner </span>
Anda juga boleh menulis middleware yang mengubah respons, dengan memanfaatkan argumen Start_FN. Berikut adalah middleware yang membalikkan output jika pengepala jenis kandungan adalah teks/biasa:
<span># Applied from bottom to top on the way in, then top to bottom on the way out </span>MIDDLEWARES <span>= [wrap_query_params, </span> log_environ<span>, </span> handle_error<span>] </span> app <span>= reduce(lambda h, m: m(h), MIDDLEWARES, handler) </span>
Ini sedikit lebih kusut terima kasih kepada pemisahan start_fn dan respons, tetapi masih boleh dilaksanakan dengan sempurna.
Juga ambil perhatian bahawa, untuk mematuhi spesifik dengan WSGI, kita mesti menyemak kaedah
pada respons dan memanggilnya jika ada. Aplikasi WSGI Legacy juga boleh mengembalikan fungsi tulis
dan bukannya sebagai pengendali panggilan; Jika anda mahu middleware anda menyokong aplikasi yang lebih lama, anda mungkin perlu mengendalikan kes ini.
Sebaik sahaja anda mula bermain dengan WSGI mentah sedikit, anda mula memahami mengapa Python mempunyai puluhan kerangka web secara harfiah. WSGI menjadikannya cukup mudah untuk membina sesuatu bermula dari awal. Sebagai contoh, anda mungkin mempertimbangkan masalah penghalaan:
<span>def reverser(handler): </span> <span># A reverse function </span> rev <span>= lambda it: it[::-1] </span> <span>def _inner(environ, start_fn): </span> do_reverse <span>= [] # Must be a reference type such as a list </span> <span># Override start_fn to check the content type and set a flag </span> <span>def start_reverser(status, headers): </span> <span>for name, value in headers: </span> <span>if (name.lower() == 'content-type' </span> <span>and value.lower() == 'text/plain'): </span> do_reverse<span>.append(True) </span> <span>break </span> <span># Remember to call `start_fn` </span> start_fn<span>(status, headers) </span> response <span>= handler(environ, start_reverser) </span> <span>try: </span> <span>if do_reverse: </span> <span>return list(rev(map(rev, response))) </span> <span>return response </span> <span>finally: </span> <span>if hasattr(response, 'close'): </span> response<span>.close() </span> <span>return _inner </span>
bekerja dengan WSGI secara langsung boleh menjadi baik jika anda menikmati fleksibiliti pemasangan perpustakaan di atas
Sudah tentu, untuk aplikasi yang tidak khusus, anda mungkin masih mahu menggunakan rangka kerja supaya kes-kes kelebihan dikendalikan dengan betul dan tidak.
tetapi bagaimana dengan pelayan?dan itu semua ada!
Soalan Lazim (Soalan Lazim) Mengenai Aplikasi Web Python dan WSGI
Menggunakan aplikasi web python menggunakan WSGI melibatkan beberapa langkah. Pertama, anda perlu memasang pelayan WSGI, seperti Gunicorn atau UWSGI. Seterusnya, anda perlu mengkonfigurasi pelayan web anda untuk menggunakan pelayan WSGI sebagai proksi untuk permintaan pengendalian ke aplikasi anda. Ini melibatkan mengubah fail konfigurasi pelayan anda untuk memasukkan tetapan WSGI yang diperlukan. Akhirnya, anda perlu memulakan pelayan WSGI anda dan menunjuknya ke fail WSGI aplikasi anda.
Bolehkah saya menggunakan WSGI dengan Flask? Malah, aplikasi Flask adalah aplikasi WSGI secara lalai. Apabila anda membuat aplikasi flask, anda sebenarnya membuat aplikasi WSGI bahawa kerangka flask akan digunakan untuk mengendalikan permintaan masuk dan menghantar respons.
Middleware WSGI adalah komponen yang terletak di antara pelayan WSGI dan aplikasi WSGI. Ia boleh memproses permintaan sebelum mereka mencapai permohonan dan respons sebelum dihantar kembali kepada pelanggan. Middleware boleh digunakan untuk melaksanakan pelbagai fungsi, seperti pengurusan sesi, penghalaan URL, dan pengesahan.
Atas ialah kandungan terperinci Aplikasi Web Python: Asas WSGI. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!