Chapter 1: Wprowadzenie

Wprowadzenie

Platforma web2py[web2py] jest darmowym frameworkiem internetowym o otwartym kodzie dla zwinnego programowania bezpiecznych aplikacji internetowych wykorzystujących bazę danych. Jest napisana w języku Python[python] i programowalna w tym języku. Jest to pełnym "framework aplikacyjny", co oznacza, że zawiera wszystkie komponenty potrzebne do zbudowania w pełni funkcjonalnej aplikacji internetowej.

Framework web2py jest zaprojektowany z myślą o wymuszeniu na programiście postępowania zgodnego z dobrymi praktykami inżynierii oprogramowania, na przykład przez stosowanie wzorca Model-Widok-Kontroler (MVC). Framework web2py oddziela reprezentację danych (model) od prezentowania danych (widok) jak również od logiki aplikacji i przepływu danych (kontroler). Framework web2py dostarcza bibliotki pomagających w projektowaniu, implementowaniu i testowaniu oddzielnie każdej z tych trzech części i sprawieniu, że będą one działać razem.

Framework web2py jest zbudowany z myślą o zapewnieniu bezpieczeństwa aplikacji. Oznacza to, że jest rozwiązanych wiele problemów, które mogą sprowadzić zagrożenie bezpieczeństwa, postępując zgodnie z dobrze wypróbowanymi praktykami. Na przykład:

  • sprawdzane są wszystkie dane wejściowe, aby zapobiec wstrzykiwaniu (ang. injection),
  • zabezpieczane są znakami ucieczki wszystkie dane wyjściowe, aby zapobiec atakom przez skrypty międzywitrynowe (ang. cross-site scripting),
  • zmieniane są nazwy ładowanych plików, aby zapobiec atakom z penetracją systemu plików (ang. directory traversal).

Framework web2py dba o główne kwestie bezpieczeństwa, tak więc programiści mają mniejsze szanse wprowadzenia luk bezpieczeństwa.

Framework web2py zawiera warstwę abstrakcji bazy danych (ang. Database Abstraction Layer – DAL), która zapisuje dynamicznie zapytania SQL[sql-w], tak że programista nie musi nic w tym zakresie robić. DAL wie jak generować przejrzyście zapytania SQL dla baz danych, takich jak SQLite[sqlite], MySQL[mysql], PostgreSQL[postgres], MSSQL[mssql], FireBird[firebird], Oracle[oracle], IBM DB2[db2], Informix[informix] czy Ingres[ingresdb].

DAL może również generować wywołania funkcji dla magazynu danych Google, który działa na Google App Engine (GAE)[gae]. Eksperymentalnie wspiera kilka dodatkowych baz danych a nowe są stale dodawane. Proszę sprawdzić nowe adaptery na stronie web2py i na listach dyskusyjnych. Zdefiniowana jest jedna lub więcej tabel bazy danych, web2py automatycznie generuje w pełni funkcjonalny internetowy interfejs administracyjny baz danych w celu umożliwienia dostępu do bazy danych i tabel.

Framework web2py różni się od innych frameworków internetowych tym, że jest platformą w pełni realizującą paradygmat Web 2.0, według którego sieć internetowa jest komputerem. W rzeczywistości web2py nie wymaga ani instalacji ani konfiguracji – jest uruchamiany w każdej architekturze, na której można uruchomić Python (Windows, Windows CE, Mac OS X, iOS i Unix/Linux). Nie wymaga też sztywnych faz programowania, wdrażania i utrzymania aplikacji. Do aplikacji można mieć dostęp za pośrednictwem lokalnego lub zdalnego interfejsu internetowego. Framework web2py uruchamia się na CPython (implementacja C) i PyPy (Python napisany w Pythonie), na wersjach Pythona 2.5, 2.6 i 2.7. Framework web2py dostarcza system biletowy dla zdarzeń błędów. Jeśli wystąpi błąd, to użytkownikowi jest wystawiany bilet a dla administratora dokonywany jest zapis w dzienniku błędów.

Framework web2py jest oprogramowaniem otwartym i jest rozpowszechniany na zasadach licencji LGPL wersja 3.

Inną ważną cechą web2py jest to, że jego twórcy zobowiązują się utrzymywać kompatybilność wsteczną w przyszłych wersjach. Zrobiliśmy tak, ponieważ pierwsze wydanie jest datowane na październik 2007. Od tego czasu zostały dodane nowe funkcjonalności frameworka oraz poprawionych zostało wiele błędów, ale jeśli jakiś program działał w web2py 1.0, to działa jeszcze lepiej obecnie.

Oto kilka przykładów wyrażeń, które ilustrują siłę i prostotę tego frameworka. Następujący kod:

db.define_table('person', Field('name'), Field('image', 'upload'))

tworzy tabele bazy danych o nazwie "person" z dwoma polami : "name" typu łańcuchowego i "image" – coś co musi być przesłane na serwer (rzeczywisty obraz). Jeśli tabela taka już istnieje, ale nie pasuje do tej definicji, to nastąpi odpowiednia zmiana istniejącej tabeli.

Dla danej tabeli, zdefiniowanej powyżej, następujący kod:

form = SQLFORM(db.person).process()

tworzy formularz dla tej tabeli umożliwiający użytkownikom przesyłanie obrazów. Sprawdza on również przesłany formularz, zmienia w bezpieczny sposób nazwę przesyłanych obrazów, zapisuje obraz w pliku, wstawia odpowiedni rekord w bazie danych, zapobiega podwójnemu przesłaniu formularza i ewentualnie zmienia sam formularz przez dodanie komunikatu błędu, jeśli przesłane przez użytkownika dane nie przechodzą walidacji.

Następujący kod osadza w pełni funkcjonalne wiki z tagami, wyszukiwaniem, chmurą tagów, uprawnieniami, załącznikami medialnymi i osadzoną obsługą:

def index(): return auth.wiki()

Natomiast kod:

@auth.requires_permission('read','person')
def f(): ....

zapobiega przed dostępem przez użytkowników do funkcji f, chyba że użytkownik jest członkiem grupy, której członkowie mają uprawnienia do odczytu rekordów tabeli "person". Jeśli użytkownik nie jest zalogowany, to nastąpi jego przekierowanie do strony logowania (domyślnie dostarczanej w web2py).

Framework web2py obsługuje również komponenty, tj. akcje, które mogą być załadowane w widoku i wchodzić w interakcję z odwiedzającymi poprzez Ajax bez ponownego ładowania strony. Dokonuje się tego poprzez helper LOAD, który umożliwia bardzo modularne tworzenie aplikacji – jest to omówione w rozdziale 3 w kontekście wiki a bardziej szczegółowo w ostatnim rozdziale książki.

Jest to 6-te wydanie książki opisujące web2py 2.4.1 i wersje następne.

Zasady

Programowanie w Pythonie zazwyczaj spełnia następujące zasady:

  • Nie powtarzaj się (Don't repeat yourself – DRY);
  • Powinien być tylko jeden sposób zrobienia określonej rzeczy;
  • Jawne jest lepsze niż niejawne.

Framework web2py w pełni jest zgodny z dwoma pierwszymi zasadami zmuszając programistę do używania najlepszych praktyk inżynierii oprogramowania, które zniechęcają do powtarzania kodu. Framework web2py prowadzi programistę przez prawie wszystkie typowe zadania w procesie programowania (tworzeni i przetwarzanie formularzy, zarządzanie sesjami, ciasteczka, błędy itd.).

żądanie

Framework web2py różni się od innych frameworków w odniesieniu do trzeciej zasady, która czasami powoduje konflikt z dwiema poprzednimi. W szczególności web2py nie importuje aplikacji użytkownika, ale wykonuje ją w określonym kontekście. Kontekst ten uwidaczniają słowa kluczowe Pythona, jak również słowa kluczowe web2py.

Dla niektórych osób może to wyglądać jak magia, ale tak nie jest. Po prostu, w praktyce, niektóre moduły są już zaimportowane bez robienia niczego. Framework web2py próbuje uniknąć irytującej cechy innych frameworków, które wymuszają na programiście importowanie tych samych modułów na początku każdego modelu i kontrolera.

Framework web2py importując własne moduły oszczędza czas i zapobiega błędom, zatem postępuje zgodnie z duchem "nie powtarzaj się" i "powinien być tylko jeden sposób na robienie rzeczy".

Jeśli programista chce użyć innych modułów Pythona lub modułów osób trzecich, to moduły muszą zostać zaimportowane jawnie, jak w każdym innym programie Pythona.

Framework internetowy

PHP
ASP
JSP

Na najbardziej podstawowym poziomie, aplikacja internetowa składa się z zestawu programów (lub funkcji), które są wykonywane, gdy są odwiedzane odpowiednie adresy URL. Osobom odwiedzającym są zwracane odpowiednie dane wyjściowe, które następnie są renderowane przez przeglądarkę.

Celem frameworków internetowych[framework] jest umożliwienie programistom szybkie budowanie nowych aplikacji, łatwo i bez błędów. Realizowane jest to przez dostarczanie interfejsów API i narzędzi, które zmniejszają i upraszczają potrzebny kod.

Są dwa klasyczne podejścia przy tworzeniu aplikacji internetowych:

  • Programowe generowanie HTML[html-w] [html-o];
  • Osadzanie kodu na stronach HTML.

Pierwszy model jest tym, który był wykorzystywany kiedyś w pierwszych skryptach CGI. Drugi model jest wykorzystywany na przyklad w PHP[php] (gdzie kod jest napisany w PHP, języku podobnym do C), ASP (gdzie kod jest napisany w Visual Basic) i JSP (gdzie kod jest napisany w Java).

Oto przykład programu PHP, który po uruchomieniu pobiera dane z bazy danych i zwraca stronę HTML z danymi wybranego rekordu:

<html><body><h1>Records</h1><?
  mysql_connect(localhost,username,password);
  @mysql_select_db(database) or die( "Unable to select database");
  $query="SELECT * FROM contacts";
  $result=mysql_query($query);
  mysql_close();
  $i=0;
  while ($i < mysql_numrows($result)) {
    $name=mysql_result($result,$i,"name");
    $phone=mysql_result($result,$i,"phone");
    echo "<b>$name</b><br>Phone:$phone<br /><br /><hr /><br />";
    $i++;
  }
?></body></html>

Problem z tym podejściem jest taki, że kod jest osadzony w HTML, lecz ten sam kod musi również generować dodatkowy HTML i generować wyrażenia SQL dla zapytań do bazy danych, wplątując wiele warstw aplikacji i utrudniając czytanie i utrzymanie takiego kodu. Sytuacja jest jeszcze gorsza dla aplikacji Ajax i złożoność rośnie wraz z liczbą stron (plików) tworzących aplikację.

Funkcjonalność przedstawioną w powyższym przykładzie można wyrazić w web2py w dwóch liniach kodu Pythona:

def index():
    return HTML(BODY(H1('Records'), db().select(db.contacts.ALL)))

W tym prostym przykładzie, struktura strony HTML jest reprezentowana programowo przez obiekty HTML, BODY i H1. Baza danych db jest odpytywana przez polecenie select. Na koniec wszystko jest serializowane w kod HTML. Proszę zauważyć, że db nie jest słowem kluczowym lecz zmienną zdefiniowaną przez użytkownika. Będziemy tej nazwy używać konsekwentnie do odniesienia do połączenia z bazą danych aby uniknąć nieporozumień.

Frameworki internetowe są zwykle kategoryzowane jako jeden z dwóch następujących typów:

  • framework "sklejany" jest zbudowany przez połączenie (sklejenie) kilku komponentów zewnętrznych (stworzonych przez osoby trzecie);
  • framework "jednolity" zbudowany jest przez utworzenie komponentów zaprojektowanych specjalnie dla tego frameworka, tak aby były ściśle ze sobą zintegrowane i działały razem.

Platforma web2py jest frameworkiem jednolitym. Prawie wszystkie jej składniki są zbudowane od podstaw i zostały zaprojektowane do wspólnego działania, ale równie dobrze mogą funkcjonować poza web2py. Na przykład, warstwa abstrakcji bazy danych (Database Abstraction Layer - DAL) lub język szablonowania mogą być używane niezależnie od platformy web2py przez zaimportowanie gluon.dal lub gluon.template do własnej aplikacji Pythona. gluon jest nazwą modułu web2py zawierającego biblioteki systemowe. Niektóre biblioteki web2py, takie jak budowanie i przetwarzanie formularzy z danymi tabel bazy danych, mają zależności od innych części web2py. Framework web2py może również działać z bibliotekami Pythona osób trzecich, włączając w to inne języki szablonowania i biblioteki DAL, ale nie będą one tak ściśle zintegrowane z oryginalnymi komponentami.

Model-Widok-Kontroler (wzorzec MVC)

Model-Widok-Kontroler
MVC
Framework web2py zachęca programistę do oddzielenia reprezentacji danych (model), prezentacji danych (widok) i działań na danych (kontroler). Rozważmy ponownie poprzedni przykład i zobaczmy jak zbudować aplikację web2py stosując wzorzec MVC. Oto przykład interfejsu edycyjnego MVC web2py:

image

Typowe przetwarzanie żądania w web2py opisuje poniższy diagram:

image

W diagramie tym:

  • Serwerem może być serwer internetowy wbudowany w web2py lub serwer zewnetrzny, taki jak Apache. Serwer obsługuje wielowątkowość.
  • "Main" to główna aplikacja WSGI. Realizuje wszystkie typowe zadania i opakowuje aplikację użytkownika. Zajmuje się ciasteczkami, sesjami, transakcjami, trasowaniem adresów URL i odwróconym trasowaniem oraz wysyłką. Może serwować i strumieniować pliki statyczne, jeśli serwer internetowy tego jeszcze nie robi.
  • Komponenty modeli, widoków i kontrolerów tworzą aplikacje użytkownika.
  • W jednej instancji web2py może być hostowanych wiele aplikacji.
  • Przerywane strzałki obrazują komunikację w motorem (-ami) bazy danych. Zapytania do bazy danych mogą być pisane w surowym SQL (niezalecane) lub przez użycie warstwy abstrakcji bazy danych (DAL) web2py (zalecane) tak że, kod aplikacji web2py nie jest zależny od od określonego motoru bazy danych.
  • Dispatcher mapuje żądane adresy URL na wywołanie funkcji w kontrolerze. Danymi wyjściowymi tej funkcji może być ciąg tekstowy lub słownik symboli (tablica asocjacyjna). Dane ze słownika są renderowane przez widok. Jeśli odwiedzający zażąda strony HTML (domyślnie), to słownik jest renderowany na stronie HTML. Jeśli odwiedzający zażąda tej samej strony w XML, web2py spróbuje odnaleźć widok, który może renderować słownik w XML. Programista może tworzyć widoki w celu renderowania stron w każdym już obsługiwanym protokole (HTML, XML, JSON, RSS, CSV i RTF) lub w dodatkowych własnych protokołach.
  • Wszystkie wywołania są opakowane w transakcjach i wszystkie przechwycone wyjątki powodują wycofanie transakcji. Jeśli przetworzenie żądania powiedzie się, to transakcja zostanie zatwierdzona.
  • Framework web2py również automatycznie obsługuje sesje i ciasteczka sesji, a gdy transakcja zostanie zatwierdzona, sesja zostanie również zapisana, o ile nie zaprojektowano tego inaczej.
  • Jest możliwe zarejestrowanie powtarzających się zadań (poprzez cron) aby uruchamiać je w zaplanowanym czasie lub po zakończeniu określonych akcji. W ten sposób możliwe jest uruchomienie w tle długich i intensywnych obliczeniowo zadań, bez spowalniania nawigacji.

Oto minimalna i kompletna aplikacja MVC, zawierająca trzy pliki:

"db.py" to model:

db = DAL('sqlite://storage.sqlite')
db.define_table('contact',
   Field('name'),
   Field('phone'))

Kod ten łączy z bazą danych (w tym przykładzie z bazą danych SQLite zapisaną w pliku storage.sqlite) i definiuje tablicę o nazwie contact. Jeśli tabela nie istnieje, web2py tworzy ją i przejrzyście, w tle generuje kod SQL w dialekcie właściwym dla stosowanego motoru bazy danych. Programista może zobaczyć wygenerowany kod SQL, ale nie musi zmieniać tego kodu, gdy bazą danych (domyślnie SQLite) jest również MySQL, PostgreSQL, MSSQL, FireBird, Oracle, DB2, Informix, Interbase, Ingres i Google App Engine (zarówno SQL i NoSQL).

Po zdefiniowaniu i utworzeniu tabeli, web2py również generuje w pełni funkcjonalny interfejs administracyjny wykorzystujący bazę danych, zwany appadmin, w celu umożliwienia dostępu do bazy danych i tabel.

"default.py" to kontroler:

def contacts():
    grid=SQLFORM.grid(db.contact, user_signature=False)
    return locals()

W web2py adresy URL są mapowane do modułów Pythona i wywołań funkcji. W tym przypadku, kontroler zawiera jedna funkcję (akcję) o nazwie contacts. Akcja może zwracać łańcuch tekstowy (zwracanie strony internetowej) lub słownik Pythona (zbiór par klucz:wartość) lub zestaw zmiennych lokalnych (jak w tym przykładzie). Jeśli funkcja zwraca słownik, to jest on przekazywany do widoku o tej samej nazwie co kontroler lub funkcja, co z kolei powoduje renderowanie strony. W tym przykładzie, funkcja contacts generuje siatkę (grid) wybierz/szukaj/utwórz/aktualizuj/usuń dla tabeli db.contact i zwraca tą siatkę do widoku.

"default/contacts.html" to widok:

{{extend 'layout.html'}}
<h1>Zarządzanie moimi kontaktami</h1>
{{=grid}}

Widok jest wywoływany automatycznie przez web2py po wykonaniu skojarzonej funkcji kontrolera (akcji). Celem widoku jest przekształcenie zmiennych w zwróconym słowniku (w naszym przypadku grid) do HTML. Plik widoku jest napisany w HTML, ale zawiera osadzony kod Pythona ograniczony specjalnymi ogranicznikami {{ i }}. Jest to zupełnie inne rozwiązanie niż w prezentowanym poprzednio przykładzie PHP, ponieważ tylko kod osadzony w HTML jest kodem "warstwy prezentacji". Plik "layout.html" przywoływany na początku kodu widoku jest dostarczany przez web2py i stanowi podstawowy układ dla wszystkich aplikacji web2py. Plik układu można łatwo zmodyfikować lub wymienić.

Dlaczego web2py

Platforma web2py jest jednym z wielu frameworków, ale ma atrakcyjne i unikalne cechy. Narzędzie to zostało pierwotnie zaprojektowane jako pomoc dydaktyczna i dzięki przyjętym założeniom w efekcie powstał pełnowartościowy profesjonalny framework internetowy. Oto jego cechy:

  • Jest łatwy w użytkowaniu i nadaje się do nauki tworzenia serwerowych aplikacji internetowych, bez utraty funkcjonalności. Z tego powodu web2py nie wymaga instalacji ani konfiguracji i nie ma zależności (z wyjątkiem kodu źródłowego, który wymaga Pythona 2.5 i jego standardowych modułów bibliotecznych) oraz eksponuje większość swoich funkcjonalności poprzez interfejs internetowy, w tym zintegrowane środowisko programistyczne z debugerem i interfejsem bazy danych.
  • Jest stabilny od pierwszego wydania, bo został zaprojektowany z góry do dołu. Czyli jego API zostało zaprojektowane w całości przed jego implementacją. Nawet gdy później dodawane były nowe funkcje, nie załamało to wstecznej kompatybilności web2py i nie załamie jej w przyszłości.
  • Aktywnie rozwiązuje najważniejsze problemy z bezpieczeństwem, które są plagą wielu nowoczesnych aplikacji internetowych, tak jak określono to w dokumencie OWASP[owasp] omówionym niżej.
  • Jest lekki. Jego rdzenne biblioteki, łącznie z warstwą abstrakcji bazy danych, językiem szablonowania i wszystkimi funkcjami pomocniczymi zajmują 1.4MB. Cały kod, łącznie z przykładową aplikacją i obrazami zajmuje 10.4MB.
  • Jest mały i bardzo szybki. Wykorzystuje internetowy serwer WSGI Rocket[rocket] zaprojektowany przez Timothy Farrella. Jest tak szybki jak Apache z modułem mod_wsgi i obsługuje SSL oraz IPv6.
  • Używa składni Pythona dla modeli, kontrolerów i widoków, ale bez konieczności importowania modeli i kontrolerów (tak jak robią to inne frameworki Pythona) – zamiast tego wykonuje je. Oznacza to, że aplikacje można instalować, odinstalowywać i modyfikować bez konieczności ponownego uruchomienia serwera internetowego (nawet produkcyjnego) i że inne aplikacje mogą współistnieć bez zakłóceń.
  • Wykorzystuje warstwę abstrakcji bazy danych (Database Abstraction Layer - DAL) zamiast relacyjnego mapowania obiektów (Object Relational Mapper - ORM). Z koncepcyjnego punktu widzenia oznacza to, że różne tabele bazy danych są odwzorowywane na różne instancje jednej klasy Table a nie na różne klasy, a rekordy są mapowane na instancje klasy Row, a nie na instancje odpowiadających im klas tabel. Z praktycznego punktu widzenia oznacza to, że składnia SQL jest odwzorowywana prawie jeden do jednego na składnię DAL i nie ma skomplikowanego programowania metaklas, tak jak ma to miejsce w popularnych bibliotekach ORM, które dodają opóźnienie.

WSGI [wsgi-w] [wsgi-o] (Web Server Gateway Interface) jest nowym standardem Pythona do komunikacji pomiędzy serwerem internetowym a aplikacją Pythona.

Oto zrzut ekranu głównego interfejsu admin web2py:

image

Bezpieczeństwo

bezpieczeństwo

Projekt Open Web Application Security Project[owasp] (OWASP) jest wolnym i otwartym działaniem społeczności światowej koncentrującym się na poprawie bezpieczeństwa oprogramowania aplikacyjnego.

Na stronach OWASP opublikowana jest pierwsza dziesiątka problemów bezpieczeństwa aplikacji internetowych o największym ryzyku. Wykaz ten został tutaj przytoczony, wraz z wyjaśnieniem, w jaki sposób dany problem został rozwiązany w web2py:

  • cross site scripting
    "Cross Site Scripting (XSS): Luki XSS występują wtedy, gdy aplikacja przetwarza dane dostarczone przez użytkownika i wysyła je do przeglądarki internetowej bez pierwotnego sprawdzenia lub zakodowania zawartości. XSS umożliwia atakującemu wykonanie złośliwego skryptu w przeglądarce ofiary, który może przejąć sesję, podmienić strony internetowe, ewentualnie wprowadzić robaki itd". Platforma web2py domyślnie zabezpiecza wszystkie zmienne przetwarzane w widoku znakami ucieczkowymi, chroniąc w ten sposób przed atakiem XSS.
  • luki iniekcyjne
    "Luki iniekcyjne: luki iniekcyjne, w szczególności wstrzykiwanie SQL są powszechne w aplikacjach internetowych. Wstrzyknięcie może nastąpić wtedy, gdy dane dostarczane przez użytkownika są wysyłane do interpretera jako część polecenia lub zapytania. Dane takie mogą zostać podmienione przez atakującego i wymusić, aby interpreter wykonał niezamierzone polecenie lub zamienił dane". Platforma web2py zawiera warstwę abstrakcji bazy danych, która uniemożliwia wstrzykiwanie kodu SQL. Zwykle wyrażenia SQL nie są pisane przez programistę, ale są generowane dynamicznie przez DAL, zapewniając, że wszystkie dane wejściowe są poprawnie zabezpieczone znakami ucieczkowymi.
  • złośliwe wykonanie pliku
    "Złośliwe wykonanie pliku: Kod narażony na zdalne dołączanie pliku (ataki Remote File Inclusion - RFI) umożliwia atakującemu dołączenie złośliwego kodu i danych, co w rezultacie może spowodować dewastacyjne ataki na serwer, nawet całkowite przejęcie serwera." Platforma web2py umożliwia tylko wykonywanie funkcji ujawnionych, zabezpieczając przed złośliwym wykonywaniem pliku. Importowane funkcje nie są nigdy ujawniane – ujawniane są tylko akcje. web2py wykorzystuje internetowy interfejs administracyjny bardzo ułatwiający śledzenie tego co jest ujawnione a co nie.
  • niebezpieczne odniesienie do obiektu
    "Niebezpieczne odniesienie bezpośrednie do obiektu (ang. Insecure Direct Object Reference): Niebezpieczne odniesienie bezpośrednie do obiektu ma miejsce wtedy, gdy programista ujawnia odniesienie do wewnętrznej implementacji obiektu, takiej jak plik, katalog, rekord bazy danej lub klucz, w postaci adresu URL lub parametru formularza. Atakujący może manipulować takimi odniesieniami w celu uzyskania dostępu do obiektów bez uwierzytelnienia". Platforma web2py nie ujawnia jakichkolwiek wewnętrznych obiektów. Ponadto sprawdza wszystkie adresy URL, co zapobiega atakom typu Directory Travelsal. web2py również dostarcza prosty mechanizm do tworzenia formularzy, w których automatycznie są sprawdzane wszystkie dane wejściowe.
  • CSRF
    "Cross Site Request Forgery (CSRF): Atak CSRF zmusza przeglądarkę zalogowanej ofiary do wysłania wcześniej uwierzytelnionego żądania do podatnej aplikacji internetowej, która następnie zmusza przeglądarkę ofiary do wykonania wrogiego działania na korzyść atakującego. Atak CSRF może być tak silny jak atakująca aplikacja internetowa." Platforma web2py zabezpiecza przed atakami CSRF a także przed przypadkowym podwójnym przesłaniem formularzy przez przypisywanie każdemu formularzowi losowego tokenu. Ponadto web2py wykorzystuje UUID dla ciasteczek sesji.
  • wyciek informacji
    niewłaściwa obsługa błędu
    "Wyciek informacji i niewłaściwa obsługa błędu: Aplikacje mogą nieumyślnie powodować wyciek informacji o konfiguracji, wewnętrznym funkcjonowaniu lub naruszanie prywatności poprzez różne problemy aplikacyjne. Atakujący może używać tej słabości do kradzieży poufnych danych lub przeprowadzić bardziej poważniejsze ataki". Platforma web2py zawiera system biletowy. Żaden błąd nie może spowodować ujawnienie kodu użytkownikom. Wszystkie błędy są zapisywane w dzienniku a bilet jest wystawiany użytkownikowi, co umożliwia śledzenie błędu. Lecz błędy i kod źródłowy są dostępne tylko administratorowi.
  • "Złamanie uwierzytelnienia i zarządzania sesją: Poświadczenia konta i tokeny sesji są często niewłaściwie chronione. Atakujący może złamać hasła, klucze lub tokeny uwierzytelniania do założenia innej tożsamości użytkownika". Platforma web2py dostarcza wbudowany mechanizm do uwierzytelniania administratora oraz prowadzi niezależne sesje dla każdej aplikacji. Interfejs administracyjny wymusza również stosowanie bezpiecznych ciasteczek sesji, gdy klientem nie jest "localhost". Dla aplikacji zawiera zaawansowane API kontroli dostępu oparte na rolach.
  • zapis kryptograficzny
    "Niebezpieczny zapis kryptograficzny: Aplikacje internetowe często korzystają z kryptografii w sposób nieprawidłowy w celu ochrony danych i realizacji poświadczeń. Atakujący wykorzystuje słabo chronione dane do kradzieży tożsamości i innych przestępstw, takich jak oszustwa kart kredytowych". Platforma web2py wykorzystuje algorytmy szyfrujące MD5 lub HMAC+SHA-512 w celu ochrony przechowywanych haseł. Dostępne są też inne algorytmy.
  • bezpieczna komunikacja
    "Niebezpieczna komunikacja: Aplikacje często nie wykorzystują szyfrowanych połączeń, gdy jest to niezbędne do ochrony komunikacji wrażliwej". Platforma web2py wykorzystuje mechanizm SSL-enabled[ssl] serwera Rocket WSGI, ale można również używać Apache lub Lighttpd i moduł mod_ssl do szyfrowania komunikacji protokołem SSL.
  • ograniczenie dostępu
    "Niestosowanie ograniczeń dostępu do adresów URL: Często aplikacja chroni wrażliwą funkcjonalność tylko przez niewyświetlanie odnośników lub adresów URL do tej funkcjonalności dla nieautoryzowanych użytkowników. Atakujący może wykorzystać tą słabość do uzyskania nieautoryzowanego dostępu poprzez bezpośrednie przesłanie adresu URL i wykonania wrogich działań". Platforma web2py odwzorowuje żądane adresy URL na moduły i funkcje Pythona. Dostarcza też mechanizm do deklarowania, czy funkcje są publiczne i czy wymagane jest uwierzytelnianie i autoryzacja. Zawarte API kontroli dostępu oparte na rolach umożliwia programistom ograniczanie dostępu do wszystkich funkcji opartych na loginie, członkostwie w grupach lub uprawnieniach opartych na grupach. Uprawnienia są bardzo szczegółowe i mogą być łączone z filtrami bazy danych do umożliwienia, przykładowo, jakiegoś dostępu do specyficznych tabel lub rekordów. web2py umożliwia również cyfrowe podpisywanie adresów URL i dostarcza API do cyfrowego podpisywania wywołań zwrotnych Ajaxa.

Platforma web2py została sprawdzona pod względem bezpieczeństwa i recenzje z tego przeglądu można znaleźć w ref.[pythonsecurity].

W "pudełku"

Kod web2py można pobrać z oficjalnej strony :

http://www.web2py.com

Platforma web2py składa się z następujących komponentów:

  • bibliotek: dostarczają podstawową funkcjonalność web2py i są dostępne programowo.
  • serwera internetowego: serwer internetowy Rocket WSGI.
  • aplikacji admin: używana do tworzenia, projektowania i zarządzania innymi aplikacjami web2py. admin dostarcza kompletne zintegrowane środowisko programistyczne (Integrated Development Environment - IDE) do tworzenia aplikacji web2py. Zawiera również inne funkcjonalności, takie jak testowanie oparte na WWW i powłokę opartą na WWW.
  • aplikacji examples: zawiera dokumentację i interaktywne przykłady. examples jest klonem oficjalnej strony internetowej web2py.com i zawiera dokumentację epydoc.
  • aplikacji welcome: podstawowy szkieletowy szablon dla innych aplikacji. Domyślnie zawiera czyste menu kaskadowe CSS i uwierzytelnianie użytkownika (omówione w rozdziale 9).

Platforma web2py jest rozpowszechniana w kodzie źródłowym oraz w kodzie binarnym dla systemów Microsoft Windows i Mac OS X.

Dystrybucję kodu źródłowego można użyć na dowolnej platformie na której uruchamiany jest Python i zawiera ona wyżej omówione komponenty. Aby uruchomić wersje źródłową trzeba mieć zainstalowany w systemie Python 2.5, 2.6 lub 2.7. Należy mieć również zainstalowany jeden z dwóch obsługiwanych motorów bazy danych. Do zastosowań testowych i lekkich aplikacji można wykorzystać bazę danych SQLite, wchodzącą w skład Pythona 2.7.

Binarne wersje web2py (dla Windows i Mac OS X) zawierają interpreter Python 2.7 i bazę danych SQLite. Technicznie, te dwa składniki nie są komponentami web2py. Dołączenie ich do dystrybucji binarnej umożliwia uruchomienie web2py zaraz po zainstalowaniu dystrybucji binarnej.

Poniższy obraz przedstawia ogólną strukturę web2py:

image

Na dole możemy znaleźć interpreter. Posuwając się ku górze odnajdziemy serwer internetowy (rocket), biblioteki i aplikacje. Każda aplikacja składa się z własnego projektu MVC (modele, kontrolery, widoki, moduły, języki, bazy danych i pliki statyczne). Każda aplikacja zawiera kod swojego własnego zaplecza administracyjnego (appadmin). Każda instancja web2py dostarcza trzy aplikacje: welcome (aplikacja szkieletowa), admin (IDE oparty na WWW) i examples (kopia witryny i przykłady).

O tej książce

Książka ta zawiera następujące rozdziały, oprócz tego wprowadzenia:

  • Rozdział 2 jest minimalnym wprowadzeniem do Pythona. Zakłada się, że czytelnik ma wiedzę zarówno proceduralnych jak i obiektowo zorientowanych technik programowania, takich jak pętle, procedury warunkowe, wywołania funkcji i klasy i obejmuje podstawową składnię Pythona. Zawiera również przykłady modułów Pythona, które są wykorzystywane w całej książce. Jeśli znasz Pythona, to możesz pominąć rozdział 2.
  • Rozdział 3 pokazuje jak rozpocząć pracę z web2py, omawiając interfejs administracyjny i prowadzi czytelnika przez różne przykłady o rosnącej złożoności: aplikację, która zwraca ciąg tekstowy, aplikację licznika, blog obrazowy i pełnowartościową aplikację wiki, która umożliwia przesyłanie obrazów i komentowanie, dostarcza uwierzytelnianie, autoryzację, usługi internetowe i kanały RSS. Podczas czytania tego rozdziału może być konieczne odniesienie się do rozdziału 2 w celu wyjaśnienia składni Pythona i do następnych rozdziałów w celu poznania szczegółów o funkcjach, które są używane.
  • Rozdział 4 obejmuje bardziej systematyczne omówienie struktury rdzenia i bibliotek: mapowanie URL, żądania, odpowiedzi, sesje, buforowanie, planowanie, zadania crona, umiędzynarodowienia oraz ogólny przepływ sterowania.
  • Rozdział 5 jest to informator o języku szablonowania używanym do budowy widoków. Pokazuje jak umieścić kod Pythona w HTML i demonstrują stosowanie helperów (obiektów, które mogą generować HTML).
  • Rozdział 6 omawia warstwę abstrakcji bazy danych (DAL). Składnia DAL jest prezentowana za pomocą szeregu przykładów.
  • Rozdział 7 omawia formularze, walidację formularzy i przetwarzanie formularzy. FORM jest helperem wysokiego poziomu do budowania formularzy. SQLFORM jest konstruktorem formularzy wysokiego poziomu. W rozdziale 7 omawiamy również API zaplecza CRUD (Create/Read/Update/Delete).
  • Rozdział 8 omawia funkcjonalności komunikacyjne, takie jak pobieranie i wysyłanie wiadomości email i SMS.
  • Rozdział 9 omawia uwierzytelnianie, autoryzację i rozszerzalny mechanizm kontroli dostępu opartego na rolach dostępny w web2py. Omówiona jest tutaj również konfiguracja poczty i CAPTCHA, ponieważ składniki te są wykorzystywane przy uwierzytelnianiu. W trzecim wydaniu książki dodaliśmy obszerne omówienie integracji z mechanizmami uwierzytelniania firm trzecich, takimi jak OpenID, OAuth, Google, Facebook, LinkedIn itd.
  • Rozdział 10 jest o tworzeniu usług internetowych w web2py. Mamy tutaj przykłady integracji z Google Web Toolkit poprzez Pyjamas oraz z Adobe Flash poprzez PyAMF.
  • Rozdział 11 traktuje o receptach web2py i jQuery. Platforma web2py jest zaprojektowana głównie do programowania po stronie serwera, ale zwiera jQuery, ponieważ stwierdziliśmy, że jest to najlepsza otwarta biblioteka JavaScript z efektami i Ajaxem. W tym rozdziale wyjaśniamy jak używać efektywnie jQuery w web2py.
  • Rozdział 12 omawia komponenty web2py i wtyczki jako sposób modułowego budowania aplikacji. Dostarczamy tu przykład wtyczki, która implementuje wiele powszechnie stosowanych funkcjonalności, takich jak wykresy, komentarze i tagowanie.
  • Rozdział 13 jest o wdrażaniu produkcyjnym aplikacji web2py. Specjalnie omawiamy tutaj wdrożenie na serwerze internetowym LAMP (który uważamy za główną alternatywę wdrożeniową). Omawiamy alternatywnie serwery internetowe i konfigurację bazy danych PostgreSQL. Przedstawiamy jak web2py działa jako usługa środowiska Microsoft Windows i wdrożenia na niektórych specyficznych platformach, w tym na Google Applications Engine, Heroku i PythonAnywhere. W tym rozdziale również omawiamy bezpieczeństwo i problemy skalowalności.
  • Rozdział 14 zawiera wiele innych recept na rozwiązywanie specyficznych zadań, w tym aktualizowanie, geokodowanie, stronicowanie, API Twittera itd.
  • Rozdział 15 są to informacje o pomocy i przyczynieniu się do rozwoju projektu, z takimi zagadnieniami jak tworzenie raportów o błędach i współtworzeniu kodu.

Książka obejmuje tylko podstawowe funkcje web2py i API, które są dostarczane wraz z web2py. Książka nie obejmuje omówienia dodatków aplikacyjnych web2py (tj. gotowych aplikacji).

Aplikacje web2py można pobrać z odpowiedniej strony [appliances].

Można znaleźć dodatkowe tematy omówione na stronach usergroup[usergroup]. Istnieje również AlterEgo[alterego], stary blog web2py i FAQ.

MARKMIN

Książka ta została napisana z użyciem składni MARKMIN (patrz rozdział 5) i jest automatycznie konwertowana do HTML, LaTeX i PDF.

Wsparcie

Głównym kanałem wsparcia jest grupa użytkowników[usergroup], z dziesiątkami wpisów każdego dnia. Nawet jeśli jesteś początkującym programistą, nie wahaj się aby zadawać pytania – z przyjemnością pomożemy. Istnieje też formalny system śledzenia błędów na https://github.com/web2py/web2py/issues. Można też uzyskać profesjonalne wsparcie (zobacz stronę internetową w celu poznania szczegółów).

Współpraca

Każda pomoc jest bardzo ceniona. Możesz pomóc innym użytkownikom w grupie użytkowników lub przez bezpośrednie składanie poprawek w programie (na stronie GitHub https://github.com/web2py/web2py). Nawet jeśli znajdziesz literówkę w tej książce lub masz poprawkę, to najlepszym sposobem pomocy jest nanoszenie przez siebie poprawek (książka jest utrzymywana w foderzerze "source" w repozytorium https://github.com/mdipierro/web2py-book). Więcej informacji o współpracy można znaleźć w Chapter 15.

Konwencje stylistyczne

Dokument PEP8[style] zawiera opis dobrych praktyk w programowaniu w Pythonie. Przekonasz się, że web2py nie zawsze przestrzega tych zasad. To nie z powodu przeoczenia lub zaniedbania – w naszym przekonaniu użytkownicy web2py powinni przestrzegać tych zasad i zachęcamy do tego. Nie zdecydowaliśmy się postępować ściśle z tymi zasadami podczas definiowania helperów web2py aby zminimalizować prawdopodobieństwo konfliktu nazewniczego z obiektami definiowanymi przez użytkownika.

Na przykład, klasa reprezentująca <div> nosi nazwę DIV, podczas gdy zgodnie z referencjami Pythona powinna być ona nazwana Div. Uważamy, że w tym konkretnym przykładzie pisownia dużymi literami "DIV" jest bardziej naturalnym wyborem. Ponadto takie podejście pozostawia programistom możliwość utworzenia klasy "Div", jeśli jest taka potrzeba. Nasza składnia również odwzorowuje w sposób naturalny notację DOM większości przeglądarek (w tym Firefox).

Według podręcznika konwencji stylistycznej Pythona, wszystkie ciągi pisane dużymi literami są zarezerwowane dla stałych a nie dla zmiennych. Kontynuując nasz przykład, nawet biorąc pod uwagę, że DIV jest klasą, to jest specjalna klasą, która nigdy nie powinna być modyfikowana przez użytkownika, ponieważ spowodowało by to załamanie innej aplikacji web2py. Dlatego uważamy, że tą klasę można potraktować jako specyficzną stałą, co dodatkowo uzasadnia nasz wybór.

Podsumowując, w web2py obowiązują następujące konwencje:

  • Nazwy helperów HTML i walidatorów pisane są dużymi literami, z powodów opisanych powyżej (na przykład DIV, A, FORM, URL).
  • Nazwa obiektu translatora, T, pisana jest dużą literą, pomimo że jest to instancja klasy, a nie sama klasa. Logicznie obiekt translatora wykonuje podobną akcję jak helper HTML, w efekcie renderuje część prezentacji. Dodatkowym powodem jest to, że T musi być łatwe do lokalizacji w kodzie i mieć krótka nazwę.
  • Nazwy klas DAL są pisane zgodnie z regułami stylizacji kodu Pythona (kapitalizowane), na przykład Table, Field, Query, Row, Rows itd.

We wszystkich innych przypadkach należy postępować zgodnie z zasadami opisanymi w Python Style Guide (PEP8), jeśli to możliwe. Na przykład nazwy wszystkich obiektów instancyjne są pisane małymi literami (request, response, session, cache), a nazwy wszystkich wewnętrznych klas powinny być kapitalizowane (rozpoczynać się od dużej litery).

We wszystkich przykładach tej książki słowa kluczowe web2py są pogrubione a komentarze są wyświetlane kursywą.

Licencja

license

Platforma web2py jest licencjonowana na zasadach licencji LGPL wersja 3. Pełny tekst licencji (angielskojęzyczny) jest dostępny na stronie "GNU Operating System"[lgpl3].

Zgodnie z LGPL możesz:

  • rozpowszechniać web2py wraz ze swoimi aplikacjami (w tym oficjalną wersję binarną web2py)
  • wydawać swoje aplikacje, które wykorzystują oficjalne biblioteki web2py pod dowolna licencją.

Musisz:

  • wyjaśnić w dokumentacji, że Twoja aplikacja wykorzystuje web2py;
  • wydawać jakiekolwiek modyfikacje bibliotek web2py pod licencją LGPLv3.

Licencja obejmuje zwykłe zastrzeżenia:

BRAK GWARANCJI DLA PROGRAMU, W ZAKRESIE DOZWOLONYM PRZEZ PRAWO. Z WYJĄTKIEM PRZYPADKÓW OŚWIADCZEŃ ZAWARTYCH NA PIŚMIE, WŁAŚCICIELE PRAW AUTORSKICH LUB INNE STRONY DOSTARCZAJĄ TEN PROGRAM “TAKI JAKI JEST” BEZ ŻADNYCH GWARANCJI, WYRAŹNYCH LUB DOROZUMIAŁYCH, W TYM, ALE NIE TYLKO, GWARANCJI PRZYDATNOŚCI HANDLOWEJ I PRZYDATNOŚCI DO OKREŚLONEGO CELU. CAŁE RYZYKO ZWIĄZANE Z JAKOŚCIĄ I DZIAŁANIEM PROGRAMU JEST TWOJE. GDYBY PROGRAM OKAZAŁ SIĘ BYĆ USZKODZONYM, TO KOSZTY KONIECZNYCH NAPRAW, SERWISU LUB POPRAWEK PONOSI UŻYTKOWNIK.

W ŻADNYM PRZYPADKU, O ILE OBOWIĄZUJACE PRAWO LUB PISEMNE UZGODNIENIA NIE STANOWIĄ INACZEJ, KAŻDY WŁAŚCICIEL PRAW AUTORSKICH LUB KAŻDA INNA STRONA, KTÓRA MODYFIKUJE LUB PRZEKAZUJE TEN PROGRAM, TAK JAK DOPUSZCZONO TO WYŻEJ, NIE BĘDĄ ODPOWIADAĆ ZA TWOJE SZKODY, W TYM SZKODY OGÓLNE, SPECJALNE, INCYDENTALNE LUB WTÓRNE WYNIKAJĄCE Z KORZYSTANIA LUB BRAKU MOŻLIWOŚCI UŻYCIA TEGO PROGRAMU (W TYM MIĘDZY INNYMI, ALE NIE TYLKO, Z POWODU UTRATY DANYCH LUB POWSTANIA BŁĘDNYCH DANYCH, Z POWODU NIEWŁAŚCIWEGO PRZETWORZENIE LUB UTRACONYCH DANYCH Z POWODU PRZERWANIA PRZETWARZANIA, PRZEZ CIEBIE LUB OSOBY TRZECIE LUB Z POWODU KOLIDOWANIA TEGO PROGRAMU Z INNYMI PROGRAMAMI), NAWET JEŚLI WŁAŚCICIEL LUB INNA STRONA NIE POWIADOMIŁA O MOŻLIWOŚCI POWSTANIA TAKICH SZKÓD.

Wersje wcześniejsze

Wcześniejsze wersje web2py, 1.0.*-1.90.*, zostały wydane na zasadzie licencji GPL2 z wyjątkami handlowymi, która w praktyce jest bardzo podobna do obecnej licencji LGPLv3.

Oprogramowanie osób trzecich dystrybuowane z web2py

Platforma web2py zawiera w folderze gluon/contrib/ oprogramowanie osób trzecich oraz rożne pliki JavaScript i CSS. Pliki te są dystrybuowane z web2py wg ich oryginalnych licencji, tak jak określono to w tych plikach.

Podziękowania

Platforma web2py została pierwotnie zaprojektowana przez Massimo Di Pierro, który zastrzegł sobie pełne prawa autorskie do tego programu. Pierwsza wersja (1.0) została wydana w październiku 2007 r. Od tego czasu program ten został adaptowany przez wielu użytkowników, z których część też przyczyniła się raportowania błędów, testowania, debugowani, nanoszenia poprawek i korekt tej książki.

Oto niektórzy z głównych programistów i współpracowników, w kolejności alfabetycznej, według imion:

Adam Bryzak, Adam Gojdas, Adrian Klaver, Alain Boulch, Alan Etkin, Alec Taylor, Alexandre Andrade, Alexey Nezhdanov, Alvaro Justen, Anand Vaidya, Anatoly Belyakov, Ander Arbelaiz, Anders Roos, Andrew Replogle, Andrew Willimott, Angelo Compagnucci, Angelo and Villas, Annet Vermeer, Anthony Bastardi, Anton Muecki, Antonio Ramos, Arun Rajeevan, Attila Csipa, Ben Goosman, Ben Reinhart, Benjamin, Bernd Rothert, Bill Ferret, Blomqvist, Boris Manojlovic, Branko Vukelic, Brent Zeiben, Brian Cottingham, Brian Harrison, Brian Meredyk, Bruno Rocha, CJ Lazell, Caleb Hattingh, Carlos Galindo, Carlos Hanson, Carsten Haese, Cedric Meyer, Charles Law, Charles Winebrinner, Chris Clark, Chris May, Chris Sanders, Christian Foster Howes, Christopher Smiga, Christopher Steel, Clavin Sim, Cliff Kachinske, Corne Dickens, Craig Younkins, Dan McGee, Dan Ragubba, Dane Wright, Danny Morgan, Daniel Gonz, Daniel Haag, Daniel Lin, Dave Stoll, David Adley, David Harrison, David Lin, David Marko, David Wagner, Denes Lengyel, Diaz Luis, Dirk Krause, Dominic Koenig, Doug Warren, Douglas Philips, Douglas Soares de Andrade, Douglas and Alan, Dustin Bensing, Elcio Ferreira, Eric Vicenti, Erwin Olario, Falko Krause, Farsheed Ashouri, Felipe Meirelles, Flavien Scheurer, Fran Boon, Francisco Gama, Fred Yanowski, Friedrich Weber, Gabriele Alberti, Gergely Kontra, Gergely Peli, Gerley Kontra, Gilson Filho, Glenn Caltech, Graham Dumpleton, Gregory Benjamin, Gustavo Di Pietro, Gyuris Szabolcs, Hamdy Abdel-Badeea, Hans C. v. Stockhausen, Hans Donner, Hans Murx, Huaiyu Wang, Ian Reinhart Geiser, Iceberg, Igor Gassko, Igor Moskvitin, Ismael Serratos, Jan Beilicke, Jay Kelkar, Jeff Bauer, Jesus Matrinez, Jim Karsten, Joachim Breitsprecher, Joakim Eriksson, Joe Barnhart, Joel Carrier, Joel Samuelsson, John Heenan, Jon Romero, Jonas Rundberg, Jonathan Benn, Jonathan Lundell, Jose Jachuf, Joseph Piron, Josh Goldfoot, Josh Jaques, Jose Vicente de Sousa, Jurgis Pralgauskis, Keith Yang, Kenji Hosoda, Kenneth Lundstr, Kirill Spitsin, Kyle Smith, Larry Weinberg, Limodou, Loren McGinnis, Louis DaPrato, Luca De Alfaro, Luca Zachetti, Lucas D'Avila, Madhukar R Pai, Manuele Presenti, Marc Abramowitz, Marcel Hellkamp, Marcel Leuthi, Marcello Della Longa, Margaret Greaney, Maria Mitica, Mariano Reingart, Marin Prajic, Marin Pranji, Marius van Niekerk, Mark Kirkwood, Mark Larsen, Mark Moore, Markus Gritsch, Mart Senecal, Martin Hufsky, Martin Mulone, Martin Weissenboeck, Mateusz Banach, Mathew Grabau, Mathieu Clabaut, Matt Doiron, Matthew Norris, Michael Fig, Michael Herman, Michael Howden, Michael Jursa, Michael Toomim, Michael Willis, Michele Comitini, Miguel Goncalves, Miguel Lopez, Mike Amy, Mike Dickun, Mike Ellis, Mike Pechkin, Milan Melena, Muhammet Aydin, Napoleon Moreno, Nathan Freeze, Niall Sweeny, Niccolo Polo, Nick Groenke, Nick Vargish, Nico de Groot, Nico Zanferrari, Nicolas Bruxer, Nik Klever, Olaf Ferger, Oliver Dain, Olivier Roch Vilato, Omi Chiba, Ondrej Such, Ont Rif, Oscar Benjamin, Osman Masood, Ovidio Marinho Falcao Neto, Pai, Panos Jee, Paolo Betti, Paolo Caruccio, Paolo Gasparello, Paolo Valleri, Patrick Breitenbach, Pearu Peterson, Peli Gergely, Pete Hunt, Peter Kirchner, Phyo Arkar Lwin, Pierre Thibault, Pieter Muller, Piotr Banasziewicz, Ramjee Ganti, Richard Gordon, Richard Ree, Robert Kooij, Robert Valentak, Roberto Perdomo, Robin Bhattacharyya, Roman Bataev, Ron McOuat, Ross Peoples, Ruijun Luo, Running Calm, Ryan Seto, Salomon Derossi, Sam Sheftel, Scott Roberts, Sebastian Ortiz, Sergey Podlesnyi, Sharriff Aina, Simone Bizzotto, Sriram Durbha, Sterling Hankins, Stuart Rackham, Telman Yusupov, Thadeus Burgess, Thomas Dallagnese, Tim Farrell, Tim Michelsen, Tim Richardson, Timothy Farrell, Tito Garrido, Tyrone Hattingh, Vasile Ermicioi, Vidul Nikolaev Petrov, Vidul Petrov, Vinicius Assef, Vladimir Donnikov, Vladyslav Kozlovsky, Vladyslav Kozlovskyy, Wang Huaiyu, Wen Gong, Wes James, Will Stevens, Yair Eshel, Yarko Tymciurak, Yoshiyuki Nakamura, Younghyun Jo, Zahariash.

Na pewno o kimś zapomniałem, za co z góry przepraszam.

W szczególności skladam podziękowania dla Anthony, Jonathana, Mariano, Bruno, Vladyslava, Martina, Nathana, Simone, Thadeusa, Tima, Iceberga, Denesa, Hansa, Christiana, Frana and Patricka za ich znaczący wkład do web2py oraz dla Anthony, Alvaro, Briana, Bruno, Denesa, Dane Denniego, Erwina, Felipe, Grahama, Jonathana, Hansa, Kyle, Marka, Margaret, Michele, Nico, Richarda, Roberto, Robina, Romana, Scotta, Shane, Sharriffa, Srirama, Sterlinga, Stuarta, Thadeusa, Wena (i innych) za korektę różnych części tej książki. Jeśli znajdziesz jakieś błędy w tej książce, to są one wyłącznie moją winą, prawdopodobnie wprowadzone w ostatniej chwili. Dziękuję również Ryanowi Steffen z Wiley Custom Learning Solutions za pomoc w publikacji pierwszego wydania tej książki.

Oprogramowanie web2py zawiera kod następujących autorów, którym chciałbym serdecznie podziękować:

Guido van Rossum za Pythona[python], Peterowi Hunt, Richardowi Gordon, Timothy Farrellowi za serwer internetowy Rocket[rocket], Christopherowi Dolivet za EditArea[editarea], Bobowi Ippolito za simplejson[simplejson], Simonowi Cusack i Grantowi Edwards za pyRTF[pyrtf], Dalke Scientific Software za pyRSS2Gen[pyrss2gen], Markowi Pilgrim za feedparser[feedparser], Trentowi Mick za markdown2[markdown2], Allanowi Saddi za fcgi.py, Evanowi Martin za moduł Python memcache[memcache], Johnowi Resig za jQuery[jquery].

Dziękuję Helmutowi Epp (rektorowi DePaul University), Davidowi Millerowi (dziekanowi College of Computing i Digital Media of DePaul University) oraz Estia Eichtenowi (członkowi MetaCryption LLC) za nieustanne zaufanie i wsparcie.

Na koniec chciałbym podziękować swojej żonie Claudii i mojemu synowi Marco, za pozwolenie mi abym wiele godzin spędził nad projektem web2py, wymianę wiadomości email z innymi użytkownikami i współpracownikami i napisał ta książkę.

 top