Hloubkový průzkum Tornada, webového frameworku a asynchronní síťové knihovny v Pythonu. Naučte se vytvářet škálovatelné a vysoce výkonné aplikace s podrobnými vysvětleními, příklady a osvědčenými postupy.
Dokumentace Tornado: Komplexní průvodce pro vývojáře z celého světa
Tornado je webový framework a asynchronní síťová knihovna v Pythonu, původně vyvinutá ve FriendFeed. Je obzvláště vhodný pro long-polling, WebSockets a další aplikace, které vyžadují dlouhodobé spojení s každým uživatelem. Jeho neblokující síťové I/O ho činí extrémně škálovatelným a výkonnou volbou pro vytváření vysoce výkonných webových aplikací. Tento komplexní průvodce vás provede klíčovými koncepty Tornada a poskytne praktické příklady, abyste mohli začít.
Co je Tornado?
Ve svém jádru je Tornado webový framework a asynchronní síťová knihovna. Na rozdíl od tradičních synchronních webových frameworků používá Tornado jednovláknovou architekturu založenou na smyčce událostí. To znamená, že dokáže zpracovat mnoho souběžných připojení, aniž by vyžadovalo vlákno pro každé připojení, což ho činí efektivnějším a škálovatelnějším.
Klíčové vlastnosti Tornada:
- Asynchronní síťování: Jádro Tornada je postaveno na asynchronním I/O, což mu umožňuje efektivně zpracovávat tisíce souběžných připojení.
- Webový framework: Zahrnuje funkce jako jsou request handlery, směrování, šablonování a autentizaci, což z něj činí kompletní webový framework.
- Podpora WebSocketů: Tornado poskytuje vynikající podporu pro WebSockets, což umožňuje komunikaci v reálném čase mezi serverem a klienty.
- Lehký a rychlý: Tornado je navrženo pro výkon, je lehké a efektivní, minimalizuje režii a maximalizuje propustnost.
- Snadné použití: I přes své pokročilé funkce je Tornado relativně snadné se naučit a používat, s jasným a dobře zdokumentovaným API.
Nastavení prostředí pro Tornado
Než se ponoříte do vývoje s Tornadem, musíte si nastavit prostředí. Zde je průvodce krok za krokem:
- Nainstalujte Python: Ujistěte se, že máte nainstalovaný Python 3.6 nebo vyšší. Můžete si ho stáhnout z oficiálních stránek Pythonu (python.org).
- Vytvořte virtuální prostředí (doporučeno): Použijte
venv
nebovirtualenv
k vytvoření izolovaného prostředí pro váš projekt:python3 -m venv myenv source myenv/bin/activate # Na Linuxu/macOS myenv\Scripts\activate # Na Windows
- Nainstalujte Tornado: Nainstalujte Tornado pomocí pip:
pip install tornado
Vaše první aplikace v Tornadu
Vytvořme jednoduchou aplikaci "Hello, World!" s Tornadem. Vytvořte soubor s názvem app.py
a přidejte následující kód:
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()
Nyní spusťte aplikaci z vašeho terminálu:
python app.py
Otevřete webový prohlížeč a přejděte na http://localhost:8888
. Měli byste vidět zprávu "Hello, World!".
Vysvětlení:
tornado.ioloop
: Jádrová smyčka událostí, která zpracovává asynchronní operace.tornado.web
: Poskytuje komponenty webového frameworku, jako jsou request handlery a směrování.MainHandler
: Request handler, který definuje, jak zpracovávat příchozí HTTP požadavky. Metodaget()
je volána pro GET požadavky.tornado.web.Application
: Vytváří aplikaci Tornado, mapuje URL vzory na request handlery.app.listen(8888)
: Spustí server, který naslouchá příchozím spojením na portu 8888.tornado.ioloop.IOLoop.current().start()
: Spustí smyčku událostí, která zpracovává příchozí požadavky a asynchronní operace.
Request Handlery a směrování
Request handlery jsou základem webových aplikací v Tornadu. Definují, jak zpracovávat příchozí HTTP požadavky na základě URL. Směrování mapuje URL na konkrétní request handlery.
Definování Request Handlerů:
Pro vytvoření request handleru poděďte třídu tornado.web.RequestHandler
a implementujte příslušné HTTP metody (get
, post
, put
, delete
, atd.).
class MyHandler(tornado.web.RequestHandler):
def get(self):
self.write("Toto je GET požadavek.")
def post(self):
data = self.request.body.decode('utf-8')
self.write(f"Přijata POST data: {data}")
Směrování:
Směrování se konfiguruje při vytváření tornado.web.Application
. Poskytnete seznam n-tic, kde každá n-tice obsahuje URL vzor a odpovídající request handler.
app = tornado.web.Application([
(r"/", MainHandler),
(r"/myhandler", MyHandler),
])
URL vzory:
URL vzory jsou regulární výrazy. Můžete použít skupiny regulárních výrazů k zachycení částí URL a jejich předání jako argumentů metodám request handleru.
class UserHandler(tornado.web.RequestHandler):
def get(self, user_id):
self.write(f"ID uživatele: {user_id}")
app = tornado.web.Application([
(r"/user/([0-9]+)", UserHandler),
])
V tomto příkladu /user/([0-9]+)
odpovídá URL jako /user/123
. Část ([0-9]+)
zachytí jednu nebo více číslic a předá je jako argument user_id
metodě get
třídy UserHandler
.
Šablonování
Tornado obsahuje jednoduchý a efektivní šablonovací systém. Šablony se používají k dynamickému generování HTML, čímž se odděluje prezentační logika od aplikační logiky.
Vytváření šablon:
Šablony se obvykle ukládají do samostatných souborů (např. index.html
). Zde je jednoduchý příklad:
<!DOCTYPE html>
<html>
<head>
<title>Moje webová stránka</title>
</head>
<body>
<h1>Vítejte, {{ name }}!</h1>
<p>Dnes je {{ today }}.</p>
</body>
</html>
Zástupné symboly {{ name }}
a {{ today }}
budou nahrazeny skutečnými hodnotami při vykreslení šablony.
Vykreslování šablon:
Pro vykreslení šablony použijte metodu render()
ve vašem request handleru:
class TemplateHandler(tornado.web.RequestHandler):
def get(self):
name = "Jan Novák"
today = "2023-10-27"
self.render("index.html", name=name, today=today)
Ujistěte se, že nastavení template_path
je správně nakonfigurováno v nastavení vaší aplikace. Standardně Tornado hledá šablony v adresáři s názvem templates
ve stejném adresáři jako soubor vaší aplikace.
app = tornado.web.Application([
(r"/template", TemplateHandler),
], template_path="templates")
Syntaxe šablon:
Šablony Tornada podporují různé funkce, včetně:
- Proměnné:
{{ variable }}
- Řízení toku:
{% if condition %} ... {% else %} ... {% end %}
,{% for item in items %} ... {% end %}
- Funkce:
{{ function(argument) }}
- Vkládání:
{% include "another_template.html" %}
- Escapování: Tornado automaticky escapuje HTML entity, aby se zabránilo útokům Cross-Site Scripting (XSS). Escapování můžete zakázat pomocí
{% raw variable %}
.
Asynchronní operace
Síla Tornada spočívá v jeho asynchronních schopnostech. Asynchronní operace umožňují vaší aplikaci provádět neblokující I/O, což zlepšuje výkon a škálovatelnost. To je obzvláště užitečné pro úkoly, které zahrnují čekání na externí zdroje, jako jsou databázové dotazy nebo síťové požadavky.
@tornado.gen.coroutine
:
Dekorátor @tornado.gen.coroutine
umožňuje psát asynchronní kód pomocí klíčového slova yield
. To způsobuje, že asynchronní kód vypadá a chová se více jako synchronní kód, což zlepšuje čitelnost a udržovatelnost.
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'))
V tomto příkladu je http_client.fetch()
asynchronní operace, která vrací Future
. Klíčové slovo yield
pozastaví provádění korutiny, dokud není Future
vyřešen. Jakmile je Future
vyřešen, korutina pokračuje a tělo odpovědi je zapsáno klientovi.
tornado.concurrent.Future
:
Future
představuje výsledek asynchronní operace, který ještě nemusí být k dispozici. Můžete použít objekty Future
k řetězení asynchronních operací a zpracování chyb.
tornado.ioloop.IOLoop
:
IOLoop
je srdcem asynchronního motoru Tornada. Monitoruje souborové deskriptory a sokety na události a předává je příslušným handlerům. Obvykle nemusíte s IOLoop
přímo interagovat, ale je důležité rozumět jeho roli při zpracování asynchronních operací.
WebSockets
Tornado poskytuje vynikající podporu pro WebSockets, což umožňuje komunikaci v reálném čase mezi serverem a klienty. WebSockets jsou ideální pro aplikace, které vyžadují obousměrnou komunikaci s nízkou latencí, jako jsou chatovací aplikace, online hry a dashboardy v reálném čase.
Vytvoření WebSocket Handleru:
Pro vytvoření WebSocket handleru poděďte třídu tornado.websocket.WebSocketHandler
a implementujte následující metody:
open()
: Voláno, když je navázáno nové WebSocket spojení.on_message(message)
: Voláno, když je od klienta přijata zpráva.on_close()
: Voláno, když je WebSocket spojení uzavřeno.
import tornado.websocket
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print("WebSocket otevřen")
def on_message(self, message):
self.write_message(f"Poslali jste: {message}")
def on_close(self):
print("WebSocket uzavřen")
def check_origin(self, origin):
return True # Povolí cross-origin WebSocket spojení
Integrace WebSocketů do vaší aplikace:
Přidejte WebSocket handler do konfiguračního směrování vaší aplikace:
app = tornado.web.Application([
(r"/ws", WebSocketHandler),
])
Implementace na straně klienta:
Na straně klienta můžete použít JavaScript k navázání WebSocket spojení a odesílání/přijímání zpráv:
const websocket = new WebSocket("ws://localhost:8888/ws");
websocket.onopen = () => {
console.log("WebSocket spojení navázáno");
websocket.send("Ahoj z klienta!");
};
websocket.onmessage = (event) => {
console.log("Přijatá zpráva:", event.data);
};
websocket.onclose = () => {
console.log("WebSocket spojení uzavřeno");
};
Autentizace a bezpečnost
Bezpečnost je kritickým aspektem vývoje webových aplikací. Tornado poskytuje několik funkcí, které vám pomohou zabezpečit vaše aplikace, včetně autentizace, autorizace a ochrany proti běžným webovým zranitelnostem.
Autentizace:
Autentizace je proces ověření identity uživatele. Tornado poskytuje vestavěnou podporu pro různá autentizační schémata, včetně:
- Autentizace založená na cookies: Ukládání uživatelských přihlašovacích údajů do cookies.
- Autentizace třetích stran (OAuth): Integrace s populárními sociálními médii jako Google, Facebook a Twitter.
- API klíče: Použití API klíčů pro autentizaci API požadavků.
Autorizace:
Autorizace je proces určení, zda má uživatel oprávnění k přístupu k určitému zdroji. Můžete implementovat autorizační logiku ve svých request handlerech k omezení přístupu na základě uživatelských rolí nebo oprávnění.
Osvědčené postupy v oblasti bezpečnosti:
- Ochrana proti Cross-Site Scripting (XSS): Tornado automaticky escapuje HTML entity, aby se zabránilo útokům XSS. Vždy používejte metodu
render()
k vykreslování šablon a vyhněte se generování HTML přímo ve vašich request handlerech. - Ochrana proti Cross-Site Request Forgery (CSRF): Povolte ochranu proti CSRF v nastavení vaší aplikace, abyste zabránili útokům CSRF.
- HTTPS: Vždy používejte HTTPS k šifrování komunikace mezi serverem a klienty.
- Validace vstupu: Validujte veškerý uživatelský vstup, abyste zabránili útokům typu injection a dalším zranitelnostem.
- Pravidelné bezpečnostní audity: Provádějte pravidelné bezpečnostní audity k identifikaci a řešení potenciálních zranitelností.
Nasazení (Deployment)
Nasazení aplikace Tornado zahrnuje několik kroků, včetně konfigurace webového serveru, nastavení správce procesů a optimalizace výkonu.
Webový server:
Tornado můžete nasadit za webový server jako Nginx nebo Apache. Webový server funguje jako reverzní proxy, který přesměrovává příchozí požadavky na aplikaci Tornado.
Správce procesů:
Správce procesů jako Supervisor nebo systemd může být použit ke správě procesu Tornado, což zajišťuje, že se automaticky restartuje, pokud dojde k jeho pádu.
Optimalizace výkonu:
- Použijte smyčku událostí připravenou pro produkci: Použijte smyčku událostí připravenou pro produkci jako
uvloop
pro zlepšení výkonu. - Povolte kompresi gzip: Povolte kompresi gzip ke snížení velikosti HTTP odpovědí.
- Ukládejte statické soubory do mezipaměti: Ukládejte statické soubory do mezipaměti, abyste snížili zátěž na server.
- Monitorujte výkon: Monitorujte výkon vaší aplikace pomocí nástrojů jako New Relic nebo Prometheus.
Internacionalizace (i18n) a lokalizace (l10n)
Při vytváření aplikací pro globální publikum je důležité zvážit internacionalizaci (i18n) a lokalizaci (l10n). i18n je proces navrhování aplikace tak, aby ji bylo možné přizpůsobit různým jazykům a regionům bez technických změn. l10n je proces přizpůsobení internacionalizované aplikace pro konkrétní jazyk nebo region přidáním místně specifických komponent a překladem textu.
Tornado a i18n/l10n
Tornado samo o sobě nemá vestavěné knihovny pro i18n/l10n. Můžete však snadno integrovat standardní knihovny Pythonu, jako je `gettext`, nebo sofistikovanější frameworky, jako je Babel, pro zpracování i18n/l10n ve vaší aplikaci Tornado.
Příklad s použitím `gettext`:
1. **Nastavte své lokální prostředí (locales):** Vytvořte adresáře pro každý jazyk, který chcete podporovat, obsahující katalogy zpráv (obvykle soubory `.mo`).
locales/
en/LC_MESSAGES/messages.mo
fr/LC_MESSAGES/messages.mo
de/LC_MESSAGES/messages.mo
2. **Extrahujte přeložitelné řetězce:** Použijte nástroj jako `xgettext` k extrakci přeložitelných řetězců z vašeho kódu v Pythonu do souboru `.po` (Portable Object). Tento soubor bude obsahovat původní řetězce a zástupné symboly pro překlady.
xgettext -d messages -o locales/messages.po your_tornado_app.py
3. **Přeložte řetězce:** Přeložte řetězce v souborech `.po` pro každý jazyk.
4. **Zkompilujte překlady:** Zkompilujte soubory `.po` do souborů `.mo` (Machine Object), které `gettext` používá za běhu.
msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo
5. **Integrujte do vaší aplikace Tornado:**
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:
# Ošetření případů, kdy locale není podporováno systémem
print(f"Locale {self.get_user_locale().code} není podporováno")
translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
translation.install()
self._ = translation.gettext
def get_current_user_locale(self):
# Logika pro určení locale uživatele (např. z hlavičky Accept-Language, nastavení uživatele atd.)
# Toto je zjednodušený příklad - budete potřebovat robustnější řešení
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. **Upravte své šablony:** Použijte funkci `_()` (vázanou na `gettext.gettext`) k označení řetězců pro překlad ve vašich šablonách.
<h1>{{ _("Vítejte na našem webu!") }}</h1>
<p>{{ _("Toto je přeložený odstavec.") }}</p>
Důležité úvahy pro globální publikum:
- **Kódování znaků:** Vždy používejte kódování UTF-8 pro podporu široké škály znaků.
- **Formátování data a času:** Používejte formátování data a času specifické pro danou lokalitu. S nastavením locale lze použít funkce Pythonu `strftime` a `strptime`.
- **Formátování čísel:** Používejte formátování čísel specifické pro danou lokalitu (např. oddělovače desetinných míst, oddělovače tisíců). Modul `locale` pro to poskytuje funkce.
- **Formátování měny:** Používejte formátování měny specifické pro danou lokalitu. Zvažte použití knihovny jako `Babel` pro pokročilejší zpracování měn.
- **Jazyky psané zprava doleva (RTL):** Podporujte jazyky RTL jako arabština a hebrejština. To může zahrnovat zrcadlení rozložení vašeho webu.
- **Kvalita překladu:** Používejte profesionální překladatele k zajištění přesných a kulturně vhodných překladů. Strojový překlad může být dobrým výchozím bodem, ale často vyžaduje lidskou kontrolu.
- **Detekce locale uživatele:** Implementujte robustní detekci locale na základě preferencí uživatele, nastavení prohlížeče nebo IP adresy. Poskytněte uživatelům způsob, jak si ručně vybrat preferovaný jazyk.
- **Testování:** Důkladně testujte svou aplikaci s různými lokalitami, abyste se ujistili, že se vše zobrazuje správně.
Pokročilá témata
Vlastní chybové stránky:
Můžete si přizpůsobit chybové stránky, které Tornado zobrazuje, když dojde k chybě. To vám umožní poskytnout uživatelsky přívětivější zážitek a zahrnout informace pro ladění.
Vlastní nastavení:
Můžete definovat vlastní nastavení v konfiguraci vaší aplikace a přistupovat k nim ve svých request handlerech. To je užitečné pro ukládání aplikačně specifických parametrů, jako jsou připojovací řetězce k databázi nebo API klíče.
Testování:
Důkladně testujte své aplikace v Tornadu, abyste zajistili, že fungují správně a bezpečně. Použijte jednotkové testy, integrační testy a end-to-end testy k pokrytí všech aspektů vaší aplikace.
Závěr
Tornado je výkonný a všestranný webový framework, který je dobře vhodný pro vytváření škálovatelných a vysoce výkonných webových aplikací. Jeho asynchronní architektura, podpora WebSocketů a snadno použitelné API z něj činí populární volbu pro vývojáře po celém světě. Dodržováním pokynů a příkladů v tomto komplexním průvodci můžete začít vytvářet vlastní aplikace v Tornadu a využívat jeho mnoha funkcí.
Nezapomeňte se obracet na oficiální dokumentaci Tornada pro nejaktuálnější informace a osvědčené postupy. Šťastné kódování!