Bagaimana kerangka kerja web Python, WSGI dan CGI cocok bersama

150

Saya memiliki akun Bluehost di mana saya dapat menjalankan skrip Python sebagai CGI. Saya kira itu adalah CGI yang paling sederhana, karena untuk menjalankan saya harus mendefinisikan yang berikut di .htaccess:

Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py

Sekarang, setiap kali saya mencari pemrograman web dengan Python, saya mendengar banyak tentang WSGI dan bagaimana sebagian besar kerangka menggunakannya. Tapi saya hanya tidak mengerti bagaimana semuanya cocok, terutama ketika server web saya diberikan (Apache berjalan di mesin host) dan bukan sesuatu yang saya benar-benar bisa mainkan (kecuali mendefinisikan .htaccessperintah).

Bagaimana WSGI , CGI, dan kerangka kerja semuanya terhubung? Apa yang perlu saya ketahui, instal, dan lakukan jika saya ingin menjalankan kerangka kerja web (katakanlah web.py atau CherryPy ) pada konfigurasi CGI dasar saya? Bagaimana cara menginstal dukungan WSGI?

Eli Bendersky
sumber

Jawaban:

242

Bagaimana WSGI, CGI, dan kerangka kerja semuanya terhubung?

Apache mendengarkan pada port 80. Ia mendapat permintaan HTTP. Itu mem-parsing permintaan untuk menemukan cara untuk merespons. Apache memiliki BANYAK pilihan untuk merespons. Salah satu cara untuk merespons adalah menggunakan CGI untuk menjalankan skrip. Cara lain untuk merespons adalah dengan hanya melayani file.

Dalam kasus CGI, Apache menyiapkan lingkungan dan memanggil skrip melalui protokol CGI. Ini adalah situasi standar Unix Fork / Exec - subproses CGI mewarisi lingkungan OS termasuk soket dan stdout. Subproses CGI menulis respons, yang kembali ke Apache; Apache mengirimkan respons ini ke browser.

CGI itu primitif dan menyebalkan. Sebagian besar karena itu fork subproses untuk setiap permintaan, dan subproses harus keluar atau menutup stdout dan stderr untuk menandakan akhir dari respons.

WSGI adalah antarmuka yang didasarkan pada pola desain CGI. Ini tidak harus CGI - tidak harus melakukan subproses untuk setiap permintaan. Itu bisa CGI, tetapi tidak harus begitu.

WSGI menambah pola desain CGI dalam beberapa cara penting. Ini mem-parsing Header Permintaan HTTP untuk Anda dan menambahkan ini ke lingkungan. Ini memasok setiap input berorientasi POST sebagai objek seperti file di lingkungan. Ini juga memberi Anda fungsi yang akan merumuskan respons, menyelamatkan Anda dari banyak detail pemformatan.

Apa yang perlu saya ketahui / instal / lakukan jika saya ingin menjalankan kerangka kerja web (mis. Web.py atau cherrypy) pada konfigurasi CGI dasar saya?

Ingat bahwa forking suatu subproses mahal. Ada dua cara untuk mengatasi ini.

  1. Tertanam mod_wsgi atau mod_pythonmenyematkan Python di dalam Apache; tidak ada proses bercabang. Apache menjalankan aplikasi Django secara langsung.

  2. Daemon mod_wsgi atau mod_fastcgimemungkinkan Apache untuk berinteraksi dengan daemon terpisah (atau "proses yang berjalan lama"), menggunakan protokol WSGI. Anda memulai proses Django Anda yang sudah berjalan lama, kemudian Anda mengkonfigurasi mod_fastcgi Apache untuk berkomunikasi dengan proses ini.

Catatan yang mod_wsgidapat bekerja dalam mode: tertanam atau daemon.

Ketika Anda membaca di mod_fastcgi, Anda akan melihat bahwa Django menggunakan flup untuk membuat antarmuka yang kompatibel dengan WSGI dari informasi yang disediakan oleh mod_fastcgi. Pipa bekerja seperti ini.

Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)

Django memiliki beberapa "django.core.handlers" untuk berbagai antarmuka.

Untuk mod_fastcgi, Django menyediakan manage.py runfcgiFLUP dan handler yang terintegrasi.

Untuk mod_wsgi, ada penangan inti untuk ini.

Bagaimana cara menginstal dukungan WSGI?

Ikuti instruksi ini.

https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki

Untuk latar belakang lihat ini

http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index

S.Lott
sumber
4
Saya tidak dapat menginstal mod_wsgi karena saya menggunakan hosting bersama. Yang saya miliki adalah dukungan fcgi. Bagaimana saya bisa menjalankan aplikasi WSGI melaluinya?
Eli Bendersky
3
+1 Itulah jawaban yang sangat bagus & menjawab banyak (tetapi tidak semua) pertanyaan yang ada dalam pikiran saya. Jawaban ini masih belum lengkap. Anda menjelaskan dengan baik tentang CGI & WSGI tetapi bagaimana hubungan & perbedaan antara FASTCGI & WSGI? Mana yang lebih baik? Bagaimana mereka bekerja? Bagaimana mod_python masuk ke dalam gambar?
cakar
14
S.Lott, daripada mengeluh ketika orang bertanya mana yang "lebih baik", mengapa tidak menyatakan "mod_wsgi lebih baik daripada X, fastcgi lebih baik untuk Y", dan jika OP memiliki pertanyaan yang lebih spesifik, mereka akan bertanya.
Gregg Lind
7
@ Greg Lind: Mengapa tidak menyatakan "mod_wsgi lebih baik daripada X, fastcgi lebih baik untuk Y"? Karena itu tidak mudah dilakukan. Ada puluhan faktor kualitas non-fungsional yang merupakan elemen dari set X dan Y. Sulit untuk menyebutkan semuanya. Jauh, jauh lebih baik bagi orang untuk mengajukan pertanyaan spesifik tentang faktor kualitas yang relevan.
S.Lott
4
Hanya untuk catatan: opsi runfcgi sudah tidak digunakan lagi sejak versi 1.7 dan dukungan FastCGI dihapus di Django 1.9.
OBu
58

Saya pikir jawaban Florian menjawab bagian pertanyaan Anda tentang "apa itu WSGI", terutama jika Anda membaca PEP .

Adapun pertanyaan yang Anda ajukan menjelang akhir:

WSGI, CGI, FastCGI dll. Adalah semua protokol untuk server web untuk menjalankan kode , dan memberikan konten dinamis yang dihasilkan. Bandingkan ini dengan penyajian web statis, di mana file HTML biasa dikirim ke klien.

CGI, FastCGI dan SCGI adalah agnostik bahasa. Anda dapat menulis skrip CGI dalam Perl, Python, C, bash, apa pun. Mendefinisikan CGI yang dieksekusi akan dipanggil, berdasarkan URL, dan bagaimana hal itu akan disebut: argumen dan lingkungan. Ini juga mendefinisikan bagaimana nilai kembali harus dikembalikan ke server web setelah eksekusi Anda selesai. Variasi pada dasarnya adalah optimisasi untuk dapat menangani lebih banyak permintaan, mengurangi latensi, dan sebagainya; konsep dasarnya sama.

WSGI hanya Python. Daripada protokol agnostik bahasa, tanda tangan fungsi standar didefinisikan:

def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']

Itu adalah aplikasi WSGI yang lengkap (jika terbatas). Server web dengan dukungan WSGI (seperti Apache dengan mod_wsgi) dapat menjalankan fungsi ini setiap kali ada permintaan.

Alasan mengapa hal ini begitu hebat adalah karena kita dapat menghindari langkah berantakan konversi dari HTTP GET / POST ke CGI ke Python, dan kembali lagi di jalan keluar. Ini adalah hubungan yang jauh lebih langsung, bersih, dan efisien.

Ini juga membuatnya jauh lebih mudah untuk memiliki kerangka kerja lama berjalan di belakang server web, jika semua yang perlu dilakukan untuk permintaan adalah panggilan fungsi. Dengan CGI biasa, Anda harus memulai seluruh kerangka kerja Anda untuk setiap permintaan individu.

Untuk mendapatkan dukungan WSGI, Anda harus menginstal modul WSGI (seperti mod_wsgi ), atau menggunakan server web dengan WSGI yang dipanggang (seperti CherryPy ). Jika tidak ada dari keduanya yang memungkinkan, Anda dapat menggunakan jembatan CGI-WSGI yang diberikan dalam PEP.

James Brady
sumber
3
Ide bodoh siapa itu untuk tidak menjadikan bahasa WSGI agnostik? Lalu apa gunanya? Mungkin juga hanya mengirimkan seluruh Python sebagai modul Apache.
Salman von Abbas
2
@SalmanPK Saya pikir ini hanya trade off. Tentunya itu tidak mudah (jika bukan tidak mungkin) untuk membuat protokol agnostik bahasa yang dapat digunakan hanya dengan mengimplementasikan fungsi dalam bahasa yang dipilih.
phunehehe
21

Anda bisa menjalankan WSGI di atas CGI seperti yang ditunjukkan Pep333 sebagai contoh. Namun setiap kali ada permintaan interpreter Python baru dimulai dan seluruh konteks (koneksi database, dll.) Perlu dibangun yang semuanya membutuhkan waktu.

Yang terbaik jika Anda ingin menjalankan WSGI adalah jika host Anda akan menginstal mod_wsgi dan membuat konfigurasi yang sesuai untuk menunda kontrol ke aplikasi Anda.

Flup adalah cara lain untuk dijalankan dengan WSGI untuk server web apa pun yang dapat berbicara FCGI , SCGI atau AJP. Dari pengalaman saya, hanya FCGI yang benar-benar berfungsi, dan dapat digunakan di Apache baik melalui mod_fastcgi atau jika Anda dapat menjalankan daemon Python terpisah dengan mod_proxy_fcgi .

WSGI adalah protokol seperti CGI, yang mendefinisikan seperangkat aturan bagaimana webserver dan kode Python dapat berinteraksi, itu didefinisikan sebagai Pep333 . Itu memungkinkan banyak webservers yang berbeda dapat menggunakan banyak kerangka kerja dan aplikasi yang berbeda menggunakan protokol aplikasi yang sama. Ini sangat bermanfaat dan membuatnya sangat berguna.

Florian Bösch
sumber
3
Apakah menjalankan WSGI di atas CGI untuk apa "flup"? Bagaimana flup terhubung ke skema?
Eli Bendersky
7

Jika Anda tidak jelas tentang semua istilah di ruang ini, dan mari kita hadapi itu, yang merupakan akronim yang sarat membingungkan, ada juga pembaca latar belakang yang baik dalam bentuk HOWTO python resmi yang membahas CGI vs FastCGI vs WSGI dan sebagainya pada: http://docs.python.org/howto/webservers.html

Richard Boardman
sumber
2
URL kedaluwarsa, saya pikir ini diperbarui satu: docs.python.org/2.7/howto/webservers.html
Stefaan
Bahan yang bagus :) Orang harus membaca pengantar resmi ini bersama dengan jawaban yang diterima.
Rick
4

Ini adalah lapisan abstraksi sederhana untuk Python, mirip dengan apa yang dimaksud dengan spesifikasi Servlet untuk Java. Sedangkan CGI benar-benar tingkat rendah dan hanya membuang barang ke lingkungan proses dan standar masuk / keluar, dua spesifikasi di atas memodelkan permintaan dan respons http sebagai konstruk dalam bahasa. Kesan saya adalah bahwa dalam Python orang belum cukup puas dengan implementasi de-facto sehingga Anda memiliki campuran implementasi referensi, dan perpustakaan tipe utilitas lain yang menyediakan hal-hal lain bersama dengan dukungan WSGI (misalnya Tempel). Tentu saja saya bisa salah, saya adalah pendatang baru di Python. Komunitas "web scripting" menghadapi masalah dari arah yang berbeda (hosting bersama, warisan CGI,

Harun
sumber