Türkçe

Python web çatısı ve asenkron ağ kütüphanesi olan Tornado'nun derinlemesine incelenmesi. Ayrıntılı açıklamalar, örnekler ve en iyi uygulamalarla ölçeklenebilir, yüksek performanslı uygulamalar oluşturmayı öğrenin.

Tornado Dokümantasyonu: Dünya Çapındaki Geliştiriciler İçin Kapsamlı Bir Kılavuz

Tornado, aslen FriendFeed'de geliştirilmiş bir Python web çatısı ve asenkron ağ kütüphanesidir. Özellikle uzun yoklama, WebSocketler ve her kullanıcıya uzun ömürlü bir bağlantı gerektiren diğer uygulamalar için çok uygundur. Engellemeyen ağ G/Ç'si, onu son derece ölçeklenebilir ve yüksek performanslı web uygulamaları oluşturmak için güçlü bir seçenek haline getirir. Bu kapsamlı kılavuz, Tornado'nun temel kavramları hakkında size yol gösterecek ve başlamanız için pratik örnekler sunacaktır.

Tornado Nedir?

Özünde Tornado, bir web çatısı ve asenkron ağ kütüphanesidir. Geleneksel senkron web çatılarının aksine Tornado, tek iş parçacıklı, olay döngüsü tabanlı bir mimari kullanır. Bu, bağlantı başına bir iş parçacığı gerektirmeden birçok eşzamanlı bağlantıyı yönetebileceği anlamına gelir, bu da onu daha verimli ve ölçeklenebilir kılar.

Tornado'nun Temel Özellikleri:

Tornado Ortamınızı Kurma

Tornado geliştirmeye başlamadan önce ortamınızı kurmanız gerekir. İşte adım adım bir kılavuz:

  1. Python'u Yükleyin: Python 3.6 veya üstünün yüklü olduğundan emin olun. Resmi Python web sitesinden (python.org) indirebilirsiniz.
  2. Sanal Ortam Oluşturun (Önerilir): Projeniz için yalıtılmış bir ortam oluşturmak için venv veya virtualenv kullanın:
    python3 -m venv myenv
    source myenv/bin/activate  # Linux/macOS üzerinde
    myenv\Scripts\activate  # Windows üzerinde
  3. Tornado'yu Yükleyin: pip kullanarak Tornado'yu yükleyin:
    pip install tornado

İlk Tornado Uygulamanız

Tornado ile basit bir "Merhaba, Dünya!" uygulaması oluşturalım. app.py adında bir dosya oluşturun ve aşağıdaki kodu ekleyin:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Hello, World!")

def make_app():
 return tornado.web.Application([
  (r"/", MainHandler),
 ])

if __name__ == "__main__":
 app = make_app()
 app.listen(8888)
 tornado.ioloop.IOLoop.current().start()

Şimdi, uygulamayı terminalinizden çalıştırın:

python app.py

Web tarayıcınızı açın ve http://localhost:8888 adresine gidin. "Merhaba, Dünya!" mesajını görmelisiniz.

Açıklama:

İstek İşleyicileri ve Yönlendirme

İstek işleyicileri, Tornado web uygulamalarının temelidir. Gelen HTTP isteklerinin URL'ye göre nasıl ele alınacağını tanımlarlar. Yönlendirme, URL'leri belirli istek işleyicilerine eşler.

İstek İşleyicilerini Tanımlama:

Bir istek işleyicisi oluşturmak için tornado.web.RequestHandler sınıfından kalıtım alın ve uygun HTTP metotlarını (get, post, put, delete, vb.) uygulayın.

class MyHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Bu bir GET isteğidir.")

 def post(self):
  data = self.request.body.decode('utf-8')
  self.write(f"Alınan POST verisi: {data}")

Yönlendirme:

Yönlendirme, tornado.web.Application oluşturulurken yapılandırılır. Her bir demetin bir URL deseni ve ilgili istek işleyicisini içerdiği bir demet listesi sağlarsınız.

app = tornado.web.Application([
 (r"/", MainHandler),
 (r"/myhandler", MyHandler),
])

URL Desenleri:

URL desenleri düzenli ifadelerdir. URL'nin bölümlerini yakalamak ve bunları istek işleyici metotlarına argüman olarak geçirmek için düzenli ifade gruplarını kullanabilirsiniz.

class UserHandler(tornado.web.RequestHandler):
 def get(self, user_id):
  self.write(f"Kullanıcı ID: {user_id}")

app = tornado.web.Application([
 (r"/user/([0-9]+)", UserHandler),
])

Bu örnekte, /user/([0-9]+), /user/123 gibi URL'lerle eşleşir. ([0-9]+) kısmı bir veya daha fazla rakamı yakalar ve bunları UserHandler'ın get metoduna user_id argümanı olarak geçirir.

Şablonlama

Tornado basit ve verimli bir şablon motoru içerir. Şablonlar, sunum mantığını uygulama mantığından ayırarak dinamik olarak HTML oluşturmak için kullanılır.

Şablon Oluşturma:

Şablonlar genellikle ayrı dosyalarda saklanır (örneğin, index.html). İşte basit bir örnek:

<!DOCTYPE html>
<html>
<head>
 <title>Benim Websitem</title>
</head>
<body>
 <h1>Hoş geldiniz, {{ name }}!</h1>
 <p>Bugün {{ today }}.</p>
</body>
</html>

{{ name }} ve {{ today }}, şablon işlendiğinde gerçek değerlerle değiştirilecek yer tutuculardır.

Şablonları İşleme:

Bir şablonu işlemek için, istek işleyicinizde render() metodunu kullanın:

class TemplateHandler(tornado.web.RequestHandler):
 def get(self):
  name = "John Doe"
  today = "2023-10-27"
  self.render("index.html", name=name, today=today)

Uygulama ayarlarınızda template_path ayarının doğru şekilde yapılandırıldığından emin olun. Varsayılan olarak Tornado, şablonları uygulama dosyanızla aynı dizindeki templates adlı bir dizinde arar.

app = tornado.web.Application([
 (r"/template", TemplateHandler),
], template_path="templates")

Şablon Sözdizimi:

Tornado şablonları, aşağıdakiler dahil olmak üzere çeşitli özellikleri destekler:

Asenkron İşlemler

Tornado'nun gücü, asenkron yeteneklerinde yatar. Asenkron işlemler, uygulamanızın engellemeyen G/Ç gerçekleştirmesine olanak tanıyarak performansı ve ölçeklenebilirliği artırır. Bu, veritabanı sorguları veya ağ istekleri gibi harici kaynakları beklemeyi içeren görevler için özellikle yararlıdır.

@tornado.gen.coroutine:

@tornado.gen.coroutine dekoratörü, yield anahtar kelimesini kullanarak asenkron kod yazmanıza olanak tanır. Bu, asenkron kodun senkron kod gibi görünmesini ve davranmasını sağlayarak okunabilirliği ve sürdürülebilirliği artırır.

import tornado.gen
import tornado.httpclient

class AsyncHandler(tornado.web.RequestHandler):
 @tornado.gen.coroutine
 def get(self):
  http_client = tornado.httpclient.AsyncHTTPClient()
  response = yield http_client.fetch("http://example.com")
  self.write(response.body.decode('utf-8'))

Bu örnekte, http_client.fetch() bir Future döndüren asenkron bir işlemdir. yield anahtar kelimesi, Future çözümlenene kadar korutinin yürütülmesini askıya alır. Future çözümlendiğinde, korutin devam eder ve yanıt gövdesi istemciye yazılır.

tornado.concurrent.Future:

Bir Future, henüz mevcut olmayabilecek bir asenkron işlemin sonucunu temsil eder. Asenkron işlemleri birbirine zincirlemek ve hataları yönetmek için Future nesnelerini kullanabilirsiniz.

tornado.ioloop.IOLoop:

IOLoop, Tornado'nun asenkron motorunun kalbidir. Dosya tanımlayıcılarını ve soketleri olaylar için izler ve bunları uygun işleyicilere gönderir. Genellikle IOLoop ile doğrudan etkileşim kurmanız gerekmez, ancak asenkron işlemleri yönetmedeki rolünü anlamak önemlidir.

WebSocketler

Tornado, sunucu ve istemciler arasında gerçek zamanlı iletişimi sağlayan WebSocketler için mükemmel destek sunar. WebSocketler, sohbet uygulamaları, çevrimiçi oyunlar ve gerçek zamanlı gösterge tabloları gibi çift yönlü, düşük gecikmeli iletişim gerektiren uygulamalar için idealdir.

Bir WebSocket İşleyicisi Oluşturma:

Bir WebSocket işleyicisi oluşturmak için, tornado.websocket.WebSocketHandler sınıfından kalıtım alın ve aşağıdaki metotları uygulayın:

import tornado.websocket

class WebSocketHandler(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket açıldı")

 def on_message(self, message):
  self.write_message(f"Gönderdiniz: {message}")

 def on_close(self):
  print("WebSocket kapatıldı")

 def check_origin(self, origin):
  return True # Kaynaklar arası WebSocket bağlantılarını etkinleştir

WebSocketleri Uygulamanıza Entegre Etme:

WebSocket işleyicisini uygulamanızın yönlendirme yapılandırmasına ekleyin:

app = tornado.web.Application([
 (r"/ws", WebSocketHandler),
])

İstemci Tarafı Uygulaması:

İstemci tarafında, bir WebSocket bağlantısı kurmak ve mesaj gönderip almak için JavaScript kullanabilirsiniz:

const websocket = new WebSocket("ws://localhost:8888/ws");

websocket.onopen = () => {
 console.log("WebSocket bağlantısı kuruldu");
 websocket.send("İstemciden merhaba!");
};

websocket.onmessage = (event) => {
 console.log("Alınan mesaj:", event.data);
};

websocket.onclose = () => {
 console.log("WebSocket bağlantısı kapatıldı");
};

Kimlik Doğrulama ve Güvenlik

Güvenlik, web uygulaması geliştirmenin kritik bir yönüdür. Tornado, kimlik doğrulama, yetkilendirme ve yaygın web güvenlik açıklarına karşı koruma dahil olmak üzere uygulamalarınızı güvence altına almanıza yardımcı olacak birkaç özellik sunar.

Kimlik Doğrulama:

Kimlik doğrulama, bir kullanıcının kimliğini doğrulama işlemidir. Tornado, aşağıdakiler dahil olmak üzere çeşitli kimlik doğrulama şemaları için yerleşik destek sağlar:

Yetkilendirme:

Yetkilendirme, bir kullanıcının belirli bir kaynağa erişim izni olup olmadığını belirleme işlemidir. Kullanıcı rollerine veya izinlerine göre erişimi kısıtlamak için istek işleyicilerinizde yetkilendirme mantığı uygulayabilirsiniz.

Güvenlik İçin En İyi Uygulamalar:

Dağıtım

Bir Tornado uygulamasını dağıtmak, bir web sunucusu yapılandırmak, bir süreç yöneticisi kurmak ve performansı optimize etmek gibi birkaç adımı içerir.

Web Sunucusu:

Tornado'yu Nginx veya Apache gibi bir web sunucusunun arkasında dağıtabilirsiniz. Web sunucusu, gelen istekleri Tornado uygulamasına ileten bir ters proxy görevi görür.

Süreç Yöneticisi:

Supervisor veya systemd gibi bir süreç yöneticisi, Tornado sürecini yönetmek için kullanılabilir ve çökmesi durumunda otomatik olarak yeniden başlatılmasını sağlar.

Performans Optimizasyonu:

Uluslararasılaştırma (i18n) ve Yerelleştirme (l10n)

Küresel bir kitle için uygulamalar oluştururken, uluslararasılaştırma (i18n) ve yerelleştirmeyi (l10n) dikkate almak önemlidir. i18n, bir uygulamanın mühendislik değişiklikleri olmadan çeşitli dillere ve bölgelere uyarlanabilmesi için tasarlanması sürecidir. l10n, uluslararasılaştırılmış bir uygulamanın, yerel ayara özgü bileşenler ekleyerek ve metinleri çevirerek belirli bir dil veya bölge için uyarlanması sürecidir.

Tornado ve i18n/l10n

Tornado'nun kendisinde yerleşik i18n/l10n kütüphaneleri yoktur. Ancak, Tornado uygulamanız içinde i18n/l10n işlemlerini yönetmek için `gettext` gibi standart Python kütüphanelerini veya Babel gibi daha gelişmiş çerçeveleri kolayca entegre edebilirsiniz.

`gettext` kullanarak örnek:

1. **Yerel ayarlarınızı kurun:** Desteklemek istediğiniz her dil için mesaj katalogları (genellikle `.mo` dosyaları) içeren dizinler oluşturun.

locales/
 en/LC_MESSAGES/messages.mo
 fr/LC_MESSAGES/messages.mo
 de/LC_MESSAGES/messages.mo

2. **Çevrilebilir dizeleri ayıklayın:** Python kodunuzdan çevrilebilir dizeleri bir `.po` dosyasına (Taşınabilir Nesne) ayıklamak için `xgettext` gibi bir araç kullanın. Bu dosya, orijinal dizeleri ve çeviriler için yer tutucuları içerecektir.

xgettext -d messages -o locales/messages.po your_tornado_app.py

3. **Dizeleri çevirin:** Her dil için `.po` dosyalarındaki dizeleri çevirin.

4. **Çevirileri derleyin:** `.po` dosyalarını, çalışma zamanında `gettext` tarafından kullanılan `.mo` dosyalarına (Makine Nesnesi) derleyin.

msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo

5. **Tornado uygulamanıza entegre edin:**

import gettext
import locale
import os
import tornado.web

class BaseHandler(tornado.web.RequestHandler):
 def initialize(self):
  try:
  locale.setlocale(locale.LC_ALL, self.get_user_locale().code)
  except locale.Error:
  # Yerel ayarın sistem tarafından desteklenmediği durumları ele alın
  print(f"Yerel ayar {self.get_user_locale().code} desteklenmiyor")

  translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
  translation.install()
  self._ = translation.gettext

 def get_current_user_locale(self):
  # Kullanıcının yerel ayarını belirleme mantığı (örn. Accept-Language başlığından, kullanıcı ayarlarından vb.)
  # Bu basitleştirilmiş bir örnektir - daha sağlam bir çözüme ihtiyacınız olacak
  accept_language = self.request.headers.get('Accept-Language', 'en')
  return tornado.locale.get(accept_language.split(',')[0].split(';')[0])

class MainHandler(BaseHandler):
 def get(self):
  self.render("index.html", _=self._)

settings = {
 "template_path": os.path.join(os.path.dirname(__file__), "templates"),
}

app = tornado.web.Application([
 (r"/", MainHandler),
], **settings)

6. **Şablonlarınızı değiştirin:** Şablonlarınızda çeviri için dizeleri işaretlemek üzere `_()` fonksiyonunu (gettext.gettext'e bağlı) kullanın.

<h1>{{ _("Web sitemize hoş geldiniz!") }}</h1>
<p>{{ _("Bu çevrilmiş bir paragraftır.") }}</p>

Küresel Kitleler İçin Önemli Hususlar:

İleri Düzey Konular

Özel Hata Sayfaları:

Bir hata oluştuğunda Tornado'nun görüntülediği hata sayfalarını özelleştirebilirsiniz. Bu, daha kullanıcı dostu bir deneyim sağlamanıza ve hata ayıklama bilgilerini dahil etmenize olanak tanır.

Özel Ayarlar:

Uygulama yapılandırmanızda özel ayarlar tanımlayabilir ve bunlara istek işleyicilerinizden erişebilirsiniz. Bu, veritabanı bağlantı dizeleri veya API anahtarları gibi uygulamaya özgü parametreleri saklamak için kullanışlıdır.

Test Etme:

Tornado uygulamalarınızın doğru ve güvenli bir şekilde çalıştığından emin olmak için kapsamlı bir şekilde test edin. Uygulamanızın tüm yönlerini kapsamak için birim testleri, entegrasyon testleri ve uçtan uca testler kullanın.

Sonuç

Tornado, ölçeklenebilir, yüksek performanslı web uygulamaları oluşturmak için çok uygun, güçlü ve çok yönlü bir web çatısıdır. Asenkron mimarisi, WebSocket desteği ve kullanımı kolay API'si, onu dünya çapındaki geliştiriciler için popüler bir seçim haline getirir. Bu kapsamlı kılavuzdaki yönergeleri ve örnekleri izleyerek, kendi Tornado uygulamalarınızı oluşturmaya başlayabilir ve birçok özelliğinden yararlanabilirsiniz.

En güncel bilgiler ve en iyi uygulamalar için resmi Tornado belgelerine başvurmayı unutmayın. Mutlu kodlamalar!