Lietuvių

Išsami „Tornado“ – „Python“ žiniatinklio karkaso ir asinchroninės tinklo bibliotekos – analizė. Sužinokite, kaip kurti mastelio keitimui pritaikytas, didelio našumo programas su išsamiais paaiškinimais, pavyzdžiais ir geriausiomis praktikomis.

Tornado dokumentacija: išsamus vadovas programuotojams visame pasaulyje

„Tornado“ yra „Python“ žiniatinklio karkasas ir asinchroninė tinklo biblioteka, iš pradžių sukurta „FriendFeed“. Ji ypač tinka ilgalaikėms apklausoms (angl. long-polling), „WebSockets“ ir kitoms programoms, kurioms reikalingas ilgalaikis ryšys su kiekvienu vartotoju. Dėl neblokuojančio tinklo įvesties/išvesties (I/O) ji yra ypač pritaikoma mastelio keitimui ir galingas pasirinkimas kuriant didelio našumo žiniatinklio programas. Šis išsamus vadovas supažindins jus su pagrindinėmis „Tornado“ koncepcijomis ir pateiks praktinių pavyzdžių, padėsiančių jums pradėti.

Kas yra „Tornado“?

Iš esmės „Tornado“ yra žiniatinklio karkasas ir asinchroninė tinklo biblioteka. Skirtingai nuo tradicinių sinchroninių žiniatinklio karkasų, „Tornado“ naudoja vienos gijos, įvykių ciklu (angl. event-loop) paremtą architektūrą. Tai reiškia, kad ji gali valdyti daug vienu metu vykstančių ryšių, nereikalaudama atskiros gijos kiekvienam ryšiui, todėl yra efektyvesnė ir labiau pritaikoma mastelio keitimui.

Pagrindinės „Tornado“ savybės:

„Tornado“ aplinkos paruošimas

Prieš pradedant kurti su „Tornado“, turėsite paruošti savo aplinką. Štai žingsnis po žingsnio vadovas:

  1. Įdiekite „Python“: Įsitikinkite, kad turite įdiegtą „Python“ 3.6 ar naujesnę versiją. Ją galite atsisiųsti iš oficialios „Python“ svetainės (python.org).
  2. Sukurkite virtualią aplinką (rekomenduojama): Naudokite venv arba virtualenv, kad sukurtumėte izoliuotą aplinką savo projektui:
    python3 -m venv myenv
    source myenv/bin/activate  # Linux/macOS
    myenv\Scripts\activate  # Windows
  3. Įdiekite „Tornado“: Įdiekite „Tornado“ naudodami pip:
    pip install tornado

Jūsų pirmoji „Tornado“ programa

Sukurkime paprastą „Hello, World!“ programą su „Tornado“. Sukurkite failą pavadinimu app.py ir pridėkite šį kodą:

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()

Dabar paleiskite programą iš savo terminalo:

python app.py

Atidarykite savo naršyklę ir eikite į http://localhost:8888. Turėtumėte pamatyti pranešimą „Hello, World!“.

Paaiškinimas:

Užklausų tvarkytuvai ir maršrutizavimas

Užklausų tvarkytuvai yra „Tornado“ žiniatinklio programų pagrindas. Jie apibrėžia, kaip tvarkyti gaunamas HTTP užklausas pagal URL. Maršrutizavimas susieja URL su konkrečiais užklausų tvarkytuvais.

Užklausų tvarkytuvų apibrėžimas:

Norėdami sukurti užklausų tvarkytuvą, paveldėkite iš tornado.web.RequestHandler ir įgyvendinkite atitinkamus HTTP metodus (get, post, put, delete ir kt.).

class MyHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("This is a GET request.")

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

Maršrutizavimas:

Maršrutizavimas konfigūruojamas kuriant tornado.web.Application. Jūs pateikiate kortežų sąrašą, kuriame kiekvienas kortežas susideda iš URL šablono ir atitinkamo užklausų tvarkytuvo.

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

URL šablonai:

URL šablonai yra reguliariosios išraiškos. Galite naudoti reguliariųjų išraiškų grupes, kad užfiksuotumėte URL dalis ir perduotumėte jas kaip argumentus užklausų tvarkytuvo metodams.

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

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

Šiame pavyzdyje /user/([0-9]+) atitinka URL, tokius kaip /user/123. Dalis ([0-9]+) užfiksuoja vieną ar daugiau skaitmenų ir perduoda juos kaip user_id argumentą UserHandler get metodui.

Šablonų naudojimas

„Tornado“ turi paprastą ir efektyvų šablonų variklį. Šablonai naudojami dinamiškai generuoti HTML, atskiriant pateikimo logiką nuo programos logikos.

Šablonų kūrimas:

Šablonai paprastai laikomi atskiruose failuose (pvz., index.html). Štai paprastas pavyzdys:

<!DOCTYPE html>
<html>
<head>
 <title>My Website</title>
</head>
<body>
 <h1>Welcome, {{ name }}!</h1>
 <p>Today is {{ today }}.</p>
</body>
</html>

{{ name }} ir {{ today }} yra vietos rezervavimo ženklai, kurie bus pakeisti tikrosiomis vertėmis, kai šablonas bus atvaizduotas.

Šablonų atvaizdavimas:

Norėdami atvaizduoti šabloną, naudokite render() metodą savo užklausų tvarkytuve:

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

Įsitikinkite, kad jūsų programos nustatymuose teisingai sukonfigūruotas template_path nustatymas. Pagal numatytuosius nustatymus, „Tornado“ ieško šablonų kataloge pavadinimu templates tame pačiame kataloge kaip ir jūsų programos failas.

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

Šablonų sintaksė:

„Tornado“ šablonai palaiko įvairias funkcijas, įskaitant:

Asinchroninės operacijos

„Tornado“ stiprybė slypi jos asinchroninėse galimybėse. Asinchroninės operacijos leidžia jūsų programai atlikti neblokuojančią įvestį/išvestį, pagerindamos našumą ir mastelio keitimo galimybes. Tai ypač naudinga užduotims, kurios apima laukimą išorinių išteklių, tokių kaip duomenų bazių užklausos ar tinklo užklausos.

@tornado.gen.coroutine:

Dekoratorius @tornado.gen.coroutine leidžia rašyti asinchroninį kodą naudojant yield raktinį žodį. Tai padaro asinchroninį kodą panašesnį į sinchroninį, pagerindamas skaitomumą ir palaikomumą.

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'))

Šiame pavyzdyje http_client.fetch() yra asinchroninė operacija, kuri grąžina Future objektą. yield raktinis žodis sustabdo korutinos vykdymą, kol Future bus išspręstas. Kai Future yra išspręstas, korutina atnaujina vykdymą ir atsakymo turinys yra rašomas klientui.

tornado.concurrent.Future:

Future atspindi asinchroninės operacijos rezultatą, kuris gali būti dar nepasiekiamas. Galite naudoti Future objektus, kad sujungtumėte asinchronines operacijas ir tvarkytumėte klaidas.

tornado.ioloop.IOLoop:

IOLoop yra „Tornado“ asinchroninio variklio širdis. Ji stebi failų deskriptorius ir lizdus dėl įvykių ir perduoda juos atitinkamiems tvarkytuvams. Paprastai jums nereikia tiesiogiai sąveikauti su IOLoop, bet svarbu suprasti jos vaidmenį tvarkant asinchronines operacijas.

„WebSockets“

„Tornado“ puikiai palaiko „WebSockets“, įgalindama realaus laiko komunikaciją tarp serverio ir klientų. „WebSockets“ idealiai tinka programoms, kurioms reikalinga dvikryptė, mažo delsos laiko komunikacija, pavyzdžiui, pokalbių programoms, internetiniams žaidimams ir realaus laiko informacinėms panelėms.

„WebSocket“ tvarkytuvo kūrimas:

Norėdami sukurti „WebSocket“ tvarkytuvą, paveldėkite iš tornado.websocket.WebSocketHandler ir įgyvendinkite šiuos metodus:

import tornado.websocket

class WebSocketHandler(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket opened")

 def on_message(self, message):
  self.write_message(f"You sent: {message}")

 def on_close(self):
  print("WebSocket closed")

 def check_origin(self, origin):
  return True # Įjungti kryžminės kilmės WebSocket ryšius

„WebSockets“ integravimas į jūsų programą:

Pridėkite „WebSocket“ tvarkytuvą į savo programos maršrutizavimo konfigūraciją:

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

Kliento pusės įgyvendinimas:

Kliento pusėje galite naudoti „JavaScript“, kad užmegztumėte „WebSocket“ ryšį ir siųstumėte/gautumėte pranešimus:

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

websocket.onopen = () => {
 console.log("WebSocket connection established");
 websocket.send("Hello from the client!");
};

websocket.onmessage = (event) => {
 console.log("Received message:", event.data);
};

websocket.onclose = () => {
 console.log("WebSocket connection closed");
};

Autentifikavimas ir saugumas

Saugumas yra kritinis žiniatinklio programų kūrimo aspektas. „Tornado“ teikia keletą funkcijų, padedančių apsaugoti jūsų programas, įskaitant autentifikavimą, autorizavimą ir apsaugą nuo įprastų žiniatinklio pažeidžiamumų.

Autentifikavimas:

Autentifikavimas yra vartotojo tapatybės patvirtinimo procesas. „Tornado“ teikia integruotą palaikymą įvairioms autentifikavimo schemoms, įskaitant:

Autorizavimas:

Autorizavimas yra procesas, nustatantis, ar vartotojas turi leidimą pasiekti tam tikrą išteklių. Galite įgyvendinti autorizavimo logiką savo užklausų tvarkytuvuose, kad apribotumėte prieigą pagal vartotojų roles ar leidimus.

Saugumo geriausios praktikos:

Diegimas

„Tornado“ programos diegimas apima kelis etapus, įskaitant žiniatinklio serverio konfigūravimą, procesų valdytojo nustatymą ir našumo optimizavimą.

Žiniatinklio serveris:

Galite diegti „Tornado“ už žiniatinklio serverio, tokio kaip „Nginx“ ar „Apache“. Žiniatinklio serveris veikia kaip atvirkštinis tarpinis serveris (angl. reverse proxy), perduodamas gaunamas užklausas „Tornado“ programai.

Procesų valdytojas:

Procesų valdytojas, toks kaip „Supervisor“ ar „systemd“, gali būti naudojamas valdyti „Tornado“ procesą, užtikrinant, kad jis būtų automatiškai paleistas iš naujo, jei sugestų.

Našumo optimizavimas:

Internacionalizacija (i18n) ir lokalizacija (l10n)

Kuriant programas pasaulinei auditorijai, svarbu atsižvelgti į internacionalizaciją (i18n) ir lokalizaciją (l10n). i18n yra programos projektavimo procesas, kad ją būtų galima pritaikyti įvairioms kalboms ir regionams be inžinerinių pakeitimų. l10n yra internacionalizuotos programos pritaikymo procesas konkrečiai kalbai ar regionui, pridedant lokalizacijai būdingus komponentus ir verčiant tekstą.

„Tornado“ ir i18n/l10n

Pats „Tornado“ neturi integruotų i18n/l10n bibliotekų. Tačiau galite lengvai integruoti standartines „Python“ bibliotekas, tokias kaip `gettext`, arba sudėtingesnius karkasus, pvz., „Babel“, kad tvarkytumėte i18n/l10n savo „Tornado“ programoje.

Pavyzdys naudojant `gettext`:

1. **Nustatykite lokalizacijas:** Sukurkite katalogus kiekvienai kalbai, kurią norite palaikyti, su pranešimų katalogais (paprastai `.mo` failais).

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

2. **Išskirkite verčiamas eilutes:** Naudokite įrankį, pvz., `xgettext`, kad išskirtumėte verčiamas eilutes iš savo „Python“ kodo į `.po` failą (Portable Object). Šiame faile bus originalios eilutės ir vietos rezervavimo ženklai vertimams.

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

3. **Išverskite eilutes:** Išverskite eilutes `.po` failuose kiekvienai kalbai.

4. **Kompiliuokite vertimus:** Kompiliuokite `.po` failus į `.mo` failus (Machine Object), kuriuos `gettext` naudoja vykdymo metu.

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

5. **Integruokite į savo „Tornado“ programą:**

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:
  # Tvarkykite atvejus, kai lokalizacija nepalaikoma sistemoje
  print(f"Locale {self.get_user_locale().code} not supported")

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

 def get_current_user_locale(self):
  # Logika vartotojo lokalizacijai nustatyti (pvz., iš Accept-Language antraštės, vartotojo nustatymų ir t.t.)
  # Tai supaprastintas pavyzdys - jums reikės patikimesnio sprendimo
  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. **Pakeiskite savo šablonus:** Naudokite `_()` funkciją (susietą su `gettext.gettext`), kad pažymėtumėte eilutes vertimui savo šablonuose.

<h1>{{ _("Welcome to our website!") }}</h1>
<p>{{ _("This is a translated paragraph.") }}</p>

Svarbūs aspektai pasaulinei auditorijai:

Pažangesnės temos

Individualizuoti klaidų puslapiai:

Galite individualizuoti klaidų puslapius, kuriuos „Tornado“ rodo įvykus klaidai. Tai leidžia jums suteikti vartotojui draugiškesnę patirtį ir įtraukti derinimo informaciją.

Individualizuoti nustatymai:

Galite apibrėžti individualizuotus nustatymus savo programos konfigūracijoje ir pasiekti juos savo užklausų tvarkytuvuose. Tai naudinga saugant programai būdingus parametrus, tokius kaip duomenų bazės prisijungimo eilutės ar API raktai.

Testavimas:

Kruopščiai testuokite savo „Tornado“ programas, kad užtikrintumėte, jog jos veikia teisingai ir saugiai. Naudokite vienetų testus, integracijos testus ir „end-to-end“ testus, kad apimtumėte visus savo programos aspektus.

Išvada

„Tornado“ yra galingas ir universalus žiniatinklio karkasas, kuris puikiai tinka kuriant mastelio keitimui pritaikytas, didelio našumo žiniatinklio programas. Dėl jo asinchroninės architektūros, „WebSocket“ palaikymo ir lengvai naudojamos API jis yra populiarus pasirinkimas programuotojams visame pasaulyje. Vadovaudamiesi šiame išsamiame vadove pateiktomis gairėmis ir pavyzdžiais, galite pradėti kurti savo „Tornado“ programas ir pasinaudoti daugeliu jos funkcijų.

Nepamirškite pasikonsultuoti su oficialia „Tornado“ dokumentacija, kad gautumėte naujausią informaciją ir geriausias praktikas. Sėkmingo programavimo!