CherryPy - Szybki przewodnik

CherryPy to platforma internetowa języka Python, która zapewnia przyjazny interfejs protokołu HTTP dla programistów Pythona. Jest również nazywany biblioteką aplikacji internetowych.

CherryPy wykorzystuje mocne strony Pythona jako dynamicznego języka do modelowania i wiązania protokołu HTTP z API. Jest to jeden z najstarszych frameworków internetowych dla Pythona, który zapewnia przejrzysty interfejs i niezawodną platformę.

Historia CherryPy

Remi Delon wydał pierwszą wersję CherryPy pod koniec czerwca 2002 roku. To był punkt wyjścia do stworzenia udanej biblioteki sieciowej Python. Remi to francuski haker, który zaufał Pythonowi jako jednej z najlepszych alternatyw dla tworzenia aplikacji internetowych.

Projekt opracowany przez Remi przyciągnął wielu programistów, którzy byli zainteresowani tym podejściem. Podejście obejmowało następujące funkcje -

  • CherryPy był blisko wzorca model-widok-kontroler.

  • Klasa CherryPy musi zostać przetworzona i skompilowana przez silnik CherryPy, aby stworzyć samodzielny moduł Pythona osadzający kompletną aplikację, a także własny wbudowany serwer WWW.

  • CherryPy może mapować adres URL i jego ciąg zapytania na wywołanie metody Pythona, na przykład -

http://somehost.net/echo?message=hello would map to echo(message='hello')

Podczas dwóch lat rozwoju projektu CherryPy, był on wspierany przez społeczność, a Remi wydał kilka ulepszonych wersji.

W czerwcu 2004 roku rozpoczęła się dyskusja na temat przyszłości projektu i tego, czy powinien on być kontynuowany w tej samej architekturze. Burza mózgów i dyskusje prowadzone przez kilku stałych uczestników projektu doprowadziły następnie do koncepcji silnika publikacji obiektów i filtrów, które wkrótce stały się podstawową częścią CherryPy2. te podstawowe idee. CherryPy 2.0 odniosło prawdziwy sukces; uznano jednak, że jego konstrukcja nadal może zostać ulepszona i wymaga refaktoryzacji.

Po dyskusjach opartych na sprzężeniach zwrotnych, API CherryPy zostało dalej zmodyfikowane w celu poprawy jego elegancji, co doprowadziło do wydania CherryPy 2.1.0 w październiku 2005. Po różnych zmianach zespół wypuścił CherryPy 2.2.0 w kwietniu 2006.

Mocne strony CherryPy

Następujące cechy CherryPy są uważane za jego mocne strony -

Prostota

Tworzenie projektu w CherryPy to proste zadanie z kilkoma wierszami kodu opracowanymi zgodnie z konwencjami i wcięciami Pythona.

CherryPy jest również bardzo modułowy. Podstawowe komponenty są dobrze zarządzane z poprawną koncepcją logiki, a klasy nadrzędne można rozszerzyć na klasy podrzędne.

Moc

CherryPy wykorzystuje całą moc Pythona. Udostępnia również narzędzia i wtyczki, które są potężnymi punktami rozszerzeń potrzebnymi do tworzenia światowej klasy aplikacji.

Otwarte źródło

CherryPy to Python Web Framework o otwartym kodzie źródłowym (na licencji BSD typu open source), co oznacza, że ​​można go używać komercyjnie po ZEROWYCH kosztach.

Pomoc społeczności

Ma oddaną społeczność, która zapewnia pełne wsparcie poprzez różnego rodzaju pytania i odpowiedzi. Społeczność stara się zapewnić pełną pomoc deweloperom, począwszy od poziomu początkującego do zaawansowanego.

Rozlokowanie

Istnieją opłacalne sposoby wdrażania aplikacji. CherryPy zawiera własny, gotowy do produkcji serwer HTTP do hostowania aplikacji. CherryPy można również wdrożyć na dowolnej bramie zgodnej ze standardem WSGI.

CherryPy jest dostępny w pakietach, takich jak większość projektów open source, które można pobrać i zainstalować na różne sposoby, które są wymienione poniżej -

  • Korzystanie z tarballu
  • Korzystanie z easy_install
  • Korzystanie z Subversion

Wymagania

Podstawowe wymagania dotyczące instalacji frameworka CherryPy obejmują -

  • Python w wersji 2.4 lub nowszej
  • CherryPy 3.0

Instalowanie modułu Pythona jest uważane za łatwy proces. Instalacja obejmuje użycie następujących poleceń.

python setup.py build
python setup.py install

Pakiety Pythona są przechowywane w następujących domyślnych katalogach -

  • W systemie UNIX lub Linux
/usr/local/lib/python2.4/site-packages
or
/usr/lib/python2.4/site-packages
  • W systemie Microsoft Windows
C:\Python or C:\Python2x
  • W systemie Mac OS
Python:Lib:site-package

Instalacja za pomocą Tarball

Tarball to skompresowane archiwum plików lub katalogu. Framework CherryPy zapewnia Tarball dla każdej wersji (alfa, beta i stabilna).

Zawiera pełny kod źródłowy biblioteki. Nazwa pochodzi od narzędzia używanego w systemie UNIX i innych systemach operacyjnych.

Oto kroki, które należy wykonać, aby zainstalować CherryPy przy użyciu kulki tar -

Step 1 - Pobierz wersję zgodnie z wymaganiami użytkownika z http://download.cherrypy.org/

Step 2- Wyszukaj katalog, w którym został pobrany Tarball i rozpakuj go. W systemie operacyjnym Linux wpisz następujące polecenie -

tar zxvf cherrypy-x.y.z.tgz

W przypadku systemu Microsoft Windows użytkownik może użyć narzędzia takiego jak 7-Zip lub Winzip, aby zdekompresować archiwum za pomocą interfejsu graficznego.

Step 3 - Przejdź do nowo utworzonego katalogu i użyj następującego polecenia, aby zbudować CherryPy -

python setup.py build

W przypadku instalacji globalnej należy użyć następującego polecenia -

python setup.py install

Instalacja za pomocą easy_install

Python Enterprise Application Kit (PEAK) udostępnia moduł Pythona o nazwie Easy Install. Ułatwia to wdrażanie pakietów Pythona. Ten moduł upraszcza procedurę pobierania, budowania i wdrażania aplikacji i produktów w języku Python.

Przed zainstalowaniem CherryPy w systemie należy zainstalować funkcję Easy Install.

Step 1 - Pobierz moduł ez_setup.py z http://peak.telecommunity.com i uruchom go z prawami administratora na komputerze: python ez_setup.py.

Step 2 - Następujące polecenie służy do instalowania łatwej instalacji.

easy_install product_name

Step 3- easy_install przeszuka indeks pakietów Pythona (PyPI), aby znaleźć dany produkt. PyPI to scentralizowane repozytorium informacji o wszystkich produktach Python.

Użyj następującego polecenia, aby wdrożyć najnowszą dostępną wersję CherryPy -

easy_install cherrypy

Step 4 - easy_install pobierze następnie CherryPy, zbuduje i zainstaluje go globalnie w twoim środowisku Python.

Instalacja przy użyciu Subversion

Instalacja CherryPy przy użyciu Subversion jest zalecana w następujących sytuacjach -

  • Funkcja istnieje lub błąd został naprawiony i jest dostępny tylko w kodzie w fazie rozwoju.

  • Gdy deweloper pracuje nad samym CherryPy.

  • Gdy użytkownik potrzebuje gałęzi z gałęzi głównej w repozytorium kontroli wersji.

  • Do naprawiania błędów w poprzedniej wersji.

Podstawową zasadą subversioning jest rejestracja repozytorium i śledzenie każdej z wersji, która zawiera serię zmian w nich.

Wykonaj następujące kroki, aby zrozumieć instalację CherryPy przy użyciu Subversion−

Step 1 - Aby użyć najnowszej wersji projektu, konieczne jest sprawdzenie folderu głównego znajdującego się w repozytorium Subversion.

Step 2 - Wprowadź następujące polecenie z powłoki-

svn co http://svn.cherrypy.org/trunk cherrypy

Step 3 - Teraz utwórz katalog CherryPy i pobierz do niego cały kod źródłowy.

Testowanie instalacji

Należy zweryfikować, czy aplikacja została poprawnie zainstalowana w systemie, czy nie w taki sam sposób, jak robimy to dla aplikacji takich jak Java.

Możesz wybrać jedną z trzech metod wymienionych w poprzednim rozdziale, aby zainstalować i wdrożyć CherryPy w swoim środowisku. CherryPy musi mieć możliwość importowania z powłoki Pythona w następujący sposób -

import cherrypy

cherrypy.__version__
'3.0.0'

Jeśli CherryPy nie jest zainstalowany globalnie w środowisku Pythona systemu lokalnego, musisz ustawić zmienną środowiskową PYTHONPATH, w przeciwnym razie wyświetli błąd w następujący sposób -

import cherrypy

Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named cherrypy

Istnieje kilka ważnych słów kluczowych, które należy zdefiniować, aby zrozumieć działanie CherryPy. Słowa kluczowe i definicje są następujące -

S.Nr Słowo kluczowe i definicja
1.

Web Server

Jest to interfejs obsługujący protokół HTTP. Jego celem jest przekształcenie żądań HTTP kierowanych do serwera aplikacji, tak aby otrzymywały odpowiedzi.

2.

Application

Jest to oprogramowanie, które zbiera informacje.

3.

Application server

Jest to komponent zawierający jedną lub więcej aplikacji

4.

Web application server

Jest to połączenie serwera WWW i serwera aplikacji.

Przykład

Poniższy przykład przedstawia przykładowy kod CherryPy -

import cherrypy

class demoExample:
   def index(self):
   return "Hello World!!!"
   index.exposed = True
cherrypy.quickstart(demoExample())

Zrozummy teraz, jak działa kod -

  • Pakiet o nazwie CherryPy jest zawsze importowany w określonej klasie, aby zapewnić prawidłowe działanie.

  • W powyższym przykładzie funkcja o nazwie index zwraca parametr „Hello World !!!”.

  • Ostatnia linia uruchamia serwer WWW i wywołuje określoną klasę (tutaj demoExample) i zwraca wartość wymienioną w domyślnym indeksie funkcji.

Przykładowy kod zwraca następujące dane wyjściowe -

CherryPy posiada własny serwer WWW (HTTP). Właśnie dlatego CherryPy jest samowystarczalny i pozwala użytkownikom uruchomić aplikację CherryPy w ciągu kilku minut od pobrania biblioteki.

Plik web server działa jako brama do aplikacji, za pomocą której śledzone są wszystkie żądania i odpowiedzi.

Aby uruchomić serwer WWW, użytkownik musi wykonać następujące wywołanie -

cherryPy.server.quickstart()

Plik internal engine of CherryPy odpowiada za następujące czynności -

  • Tworzenie i zarządzanie obiektami żądań i odpowiedzi.
  • Kontrolowanie i zarządzanie procesem CherryPy.

CherryPy - Konfiguracja

Framework posiada własny system konfiguracji umożliwiający parametryzację serwera HTTP. Ustawienia konfiguracji można przechowywać w pliku tekstowym o składni zbliżonej do formatu INI lub jako kompletny słownik Pythona.

Aby skonfigurować instancję serwera CherryPy, programista musi użyć globalnej sekcji ustawień.

global_conf = {
   'global': {
      'server.socket_host': 'localhost',
      'server.socket_port': 8080,
   },
}

application_conf = {
   '/style.css': {
      'tools.staticfile.on': True,
      'tools.staticfile.filename': os.path.join(_curdir, 'style.css'),
   }
}

This could be represented in a file like this:
[global]
server.socket_host = "localhost"
server.socket_port = 8080
[/style.css]
tools.staticfile.on = True
tools.staticfile.filename = "/full/path/to.style.css"

Zgodność z HTTP

CherryPy rozwijało się powoli, ale obejmuje kompilację specyfikacji HTTP z obsługą HTTP / 1.0, później przesyłane z obsługą HTTP / 1.1.

Mówi się, że CherryPy jest warunkowo zgodny z HTTP / 1.1, ponieważ implementuje wszystkie wymagane i wymagane poziomy, ale nie wszystkie wymagane poziomy specyfikacji. Dlatego CherryPy obsługuje następujące funkcje protokołu HTTP / 1.1 -

  • Jeśli klient twierdzi, że obsługuje protokół HTTP / 1.1, musi wysłać pole nagłówka w każdym żądaniu wykonanym przy użyciu określonej wersji protokołu. Jeśli nie zostanie to zrobione, CherryPy natychmiast przerwie przetwarzanie żądania.

  • CherryPy generuje pole nagłówka Date, które jest używane we wszystkich konfiguracjach.

  • CherryPy może obsłużyć kod statusu odpowiedzi (100) przy wsparciu klientów.

  • Wbudowany serwer HTTP CherryPy obsługuje trwałe połączenia, które są domyślne w HTTP / 1.1, poprzez użycie nagłówka Connection: Keep-Alive.

  • CherryPy obsługuje poprawnie podzielone żądania i odpowiedzi.

  • CherryPy obsługuje żądania na dwa różne sposoby - nagłówki If-Modified-Since i If-Unmodified-Since i wysyła odpowiedzi zgodnie z żądaniami.

  • CherryPy zezwala na dowolną metodę HTTP.

  • CherryPy obsługuje kombinacje wersji HTTP między klientem a ustawieniami serwera.

Serwer aplikacji wielowątkowych

CherryPy został zaprojektowany w oparciu o koncepcję wielowątkowości. Za każdym razem, gdy programista pobiera lub ustawia wartość w przestrzeni nazw CherryPy, odbywa się to w środowisku wielowątkowym.

Zarówno cherrypy.request, jak i cherrypy.response są kontenerami danych wątków, co oznacza, że ​​aplikacja wywołuje je niezależnie, wiedząc, które żądanie jest przez nie przekazywane w czasie wykonywania.

Serwery aplikacji wykorzystujące wzorzec wątków nie są wysoko cenione, ponieważ użycie wątków jest postrzegane jako zwiększające prawdopodobieństwo wystąpienia problemów z powodu wymagań dotyczących synchronizacji.

Inne alternatywy obejmują -

Wzorzec wieloprocesowy

Każde żądanie jest obsługiwane przez własny proces w Pythonie. Tutaj wydajność i stabilność serwera można uznać za lepsze.

Wzorzec asynchroniczny

Tutaj akceptowanie nowych połączeń i wysyłanie danych z powrotem do klienta odbywa się asynchronicznie z procesu żądania. Ta technika jest znana ze swojej skuteczności.

Wysyłanie adresów URL

Społeczność CherryPy chce być bardziej elastyczna i że inne rozwiązania dla dyspozytorów będą docenione. CherryPy 3 zapewnia inne wbudowane dyspozytory i oferuje prosty sposób pisania i używania własnych dyspozytorów.

  • Aplikacje służące do tworzenia metod HTTP. (GET, POST, PUT itp.)
  • Ten, który definiuje trasy w adresie URL - Routes Dispatcher

Dyspozytor metod HTTP

W niektórych aplikacjach identyfikatory URI są niezależne od akcji, jaką ma wykonać serwer na zasobie.

Na przykład,http://xyz.com/album/delete/10

Identyfikator URI zawiera operację, którą klient chce wykonać.

Domyślnie dyspozytor CherryPy mapowałby w następujący sposób -

album.delete(12)

Wspomniany wyżej dyspozytor jest wymieniony poprawnie, ale można go uniezależnić w następujący sposób -

http://xyz.com/album/10

Użytkownik może się zastanawiać, w jaki sposób serwer wysyła dokładną stronę. Te informacje są przenoszone przez samo żądanie HTTP. Kiedy pojawia się żądanie od klienta do serwera, CherryPy wygląda na najlepiej dopasowaną procedurę obsługi, procedura jest reprezentacją zasobu, do którego skierowany jest identyfikator URI.

DELETE /album/12 HTTP/1.1

Dyspozytor tras

Oto lista parametrów metody wymaganej przy wysyłce -

  • Parametr name to unikatowa nazwa trasy do połączenia.

  • Trasa jest wzorcem dopasowującym identyfikatory URI.

  • Kontroler to instancja zawierająca programy obsługi stron.

  • Użycie modułu rozsyłającego Routes łączy wzorzec pasujący do identyfikatorów URI i kojarzy określoną procedurę obsługi strony.

Przykład

Weźmy przykład, aby zrozumieć, jak to działa -

import random
import string
import cherrypy

class StringMaker(object):
   @cherrypy.expose
   def index(self):
      return "Hello! How are you?"
   
   @cherrypy.expose
   def generate(self, length=9):
      return ''.join(random.sample(string.hexdigits, int(length)))
		
if __name__ == '__main__':
   cherrypy.quickstart(StringMaker ())

Postępuj zgodnie z instrukcjami podanymi poniżej, aby uzyskać dane wyjściowe powyższego kodu -

Step 1 - Zapisz powyższy plik jako tutRoutes.py.

Step 2 - Odwiedź następujący adres URL -

http://localhost:8080/generate?length=10

Step 3 - Otrzymasz następujący wynik -

W CherryPy wbudowane narzędzia oferują pojedynczy interfejs do wywoływania biblioteki CherryPy. Narzędzia zdefiniowane w CherryPy można zaimplementować na następujące sposoby -

  • Z ustawień konfiguracyjnych
  • Jako dekorator Pythona lub za pośrednictwem specjalnego atrybutu _cp_config programu obsługi stron
  • Jako wywoływalny Python, który można zastosować w dowolnej funkcji

Podstawowe narzędzie uwierzytelniania

Celem tego narzędzia jest zapewnienie podstawowego uwierzytelnienia aplikacji zaprojektowanej w aplikacji.

Argumenty

To narzędzie używa następujących argumentów -

Nazwa Domyślna Opis
królestwo Nie dotyczy Łańcuch określający wartość dziedziny.
użytkowników Nie dotyczy Słownik w postaci - nazwa użytkownika: hasło lub funkcja wywoływana w Pythonie zwracająca taki słownik.
zaszyfrować Żaden Python wywoływalny używany do szyfrowania hasła zwracanego przez klienta i porównywania go z zaszyfrowanym hasłem podanym w słowniku użytkowników.

Przykład

Weźmy przykład, aby zrozumieć, jak to działa -

import sha
import cherrypy

class Root:
@cherrypy.expose
def index(self):

return """
<html>
   <head></head>
   <body>
      <a href = "admin">Admin </a>
   </body>
</html>
""" 

class Admin:

@cherrypy.expose
def index(self):
return "This is a private area"

if __name__ == '__main__':
def get_users():
# 'test': 'test'
return {'test': 'b110ba61c4c0873d3101e10871082fbbfd3'}
def encrypt_pwd(token):

return sha.new(token).hexdigest()
   conf = {'/admin': {'tools.basic_auth.on': True,
      tools.basic_auth.realm': 'Website name',
      'tools.basic_auth.users': get_users,
      'tools.basic_auth.encrypt': encrypt_pwd}}
   root = Root()
root.admin = Admin()
cherrypy.quickstart(root, '/', config=conf)

Plik get_usersfunkcja zwraca słownik zakodowany na stałe, ale także pobiera wartości z bazy danych lub gdziekolwiek indziej. Administrator klasy zawiera tę funkcję, która wykorzystuje wbudowane narzędzie do uwierzytelniania CherryPy. Uwierzytelnianie szyfruje hasło i identyfikator użytkownika.

Podstawowe narzędzie uwierzytelniające nie jest naprawdę bezpieczne, ponieważ hasło może zostać zakodowane i odszyfrowane przez intruza.

Narzędzie do buforowania

Celem tego narzędzia jest zapewnienie buforowania pamięci treści generowanych przez CherryPy.

Argumenty

To narzędzie używa następujących argumentów -

Nazwa Domyślna Opis
invalid_methods („POST”, „PUT”, „DELETE”) Krotki ciągów metod HTTP, które nie mają być buforowane. Te metody również unieważnią (usuną) każdą kopię zasobu w pamięci podręcznej.
cache_Class MemoryCache Obiekt klasy, który ma być używany do buforowania

Narzędzie do dekodowania

Celem tego narzędzia jest dekodowanie parametrów żądań przychodzących.

Argumenty

To narzędzie używa następujących argumentów -

Nazwa Domyślna Opis
kodowanie Żaden Szuka nagłówka typu zawartości
Kodowanie_domyślne „UTF-8” Domyślne kodowanie, które ma być używane, gdy nie podano lub nie znaleziono.

Przykład

Weźmy przykład, aby zrozumieć, jak to działa -

import cherrypy
from cherrypy import tools

class Root:
@cherrypy.expose
def index(self):

return """ 
<html>
   <head></head>
   <body>
      <form action = "hello.html" method = "post">
         <input type = "text" name = "name" value = "" />
         <input type = ”submit” name = "submit"/>
      </form>
   </body>
</html>
"""

@cherrypy.expose
@tools.decode(encoding='ISO-88510-1')
def hello(self, name):
return "Hello %s" % (name, )
if __name__ == '__main__':
cherrypy.quickstart(Root(), '/')

Powyższy kod pobiera ciąg znaków od użytkownika i przekieruje użytkownika na stronę „hello.html”, gdzie zostanie wyświetlony jako „Hello” z podaną nazwą.

Dane wyjściowe powyższego kodu są następujące -

hello.html

Aplikacje z pełnym stosem zapewniają możliwość tworzenia nowej aplikacji za pomocą polecenia lub wykonania pliku.

Rozważ aplikacje w Pythonie, takie jak framework web2py; cały projekt / aplikacja jest tworzona pod kątem frameworka MVC. Podobnie CherryPy pozwala użytkownikowi ustawić i skonfigurować układ kodu zgodnie z ich wymaganiami.

W tym rozdziale dowiemy się szczegółowo, jak stworzyć aplikację CherryPy i jak ją uruchomić.

System plików

System plików aplikacji pokazano na poniższym zrzucie ekranu -

Oto krótki opis różnych plików, które mamy w systemie plików -

  • config.py- Każda aplikacja potrzebuje pliku konfiguracyjnego i sposobu jego załadowania. Tę funkcjonalność można zdefiniować w config.py.

  • controllers.py- MVC to popularny wzorzec projektowy, za którym podążają użytkownicy. W pliku controllers.py zaimplementowane są wszystkie obiekty, które zostaną zamontowane na drzewie cherrypy.py .

  • models.py - Ten plik współdziała z bazą danych bezpośrednio w przypadku niektórych usług lub przechowywania trwałych danych.

  • server.py - Ten plik współdziała z serwerem WWW gotowym do produkcji, który działa poprawnie z proxy równoważenia obciążenia.

  • Static - Zawiera wszystkie pliki CSS i pliki graficzne.

  • Views - Zawiera wszystkie pliki szablonów dla danej aplikacji.

Przykład

Poznajmy szczegółowo kroki, aby utworzyć aplikację CherryPy.

Step 1 - Utwórz aplikację, która powinna zawierać aplikację.

Step 2- W katalogu utwórz pakiet Pythona odpowiadający projektowi. Utwórz katalog gedit i dołącz do niego plik _init_.py.

Step 3 - Wewnątrz pakietu umieść plik controllers.py o następującej zawartości -

#!/usr/bin/env python

import cherrypy

class Root(object):

   def __init__(self, data):
      self.data = data

   @cherrypy.expose
   def index(self):
      return 'Hi! Welcome to your application'

def main(filename):
   data = {} # will be replaced with proper functionality later

   # configuration file
   cherrypy.config.update({
      'tools.encode.on': True, 'tools.encode.encoding': 'utf-8',
      'tools.decode.on': True,
      'tools.trailing_slash.on': True,
      'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)),
   })

   cherrypy.quickstart(Root(data), '/', {
      '/media': {
         'tools.staticdir.on': True,
         'tools.staticdir.dir': 'static'
      }
   })
	
if __name__ == '__main__':
main(sys.argv[1])

Step 4- Rozważ aplikację, w której użytkownik wprowadza wartość za pomocą formularza. Uwzględnijmy w aplikacji dwa formularze - index.html i submit.html.

Step 5 - W powyższym kodzie dla kontrolerów mamy index(), która jest funkcją domyślną i ładuje się jako pierwsza, jeśli wywoływany jest określony kontroler.

Step 6 - Wdrożenie index() metodę można zmienić w następujący sposób -

@cherrypy.expose
   def index(self):
      tmpl = loader.load('index.html')
	 
      return tmpl.generate(title='Sample').render('html', doctype='html')

Step 7- Spowoduje to załadowanie index.html po uruchomieniu danej aplikacji i skierowanie jej do podanego strumienia wyjściowego. Plik index.html jest następujący -

index.html

<!DOCTYPE html >
<html>
   <head>
      <title>Sample</title>
   </head>
	
   <body class = "index">
      <div id = "header">
         <h1>Sample Application</h1>
      </div>
		
      <p>Welcome!</p>
		
      <div id = "footer">
         <hr>
      </div>
		
   </body>
	
</html>

Step 8 - Ważne jest, aby dodać metodę do klasy Root w programie controller.py jeśli chcesz utworzyć formularz, który akceptuje wartości, takie jak nazwy i tytuły.

@cherrypy.expose
   def submit(self, cancel = False, **value):
	
      if cherrypy.request.method == 'POST':
         if cancel:
            raise cherrypy.HTTPRedirect('/') # to cancel the action
         link = Link(**value)
         self.data[link.id] = link
         raise cherrypy.HTTPRedirect('/')
      tmp = loader.load('submit.html')
      streamValue = tmp.generate()
		
      return streamValue.render('html', doctype='html')

Step 9 - Kod, który należy umieścić w pliku submit.html, jest następujący -

<!DOCTYPE html>
   <head>
      <title>Input the new link</title>
   </head>
	
   <body class = "submit">
      <div id = " header">
         <h1>Submit new link</h1>
      </div>
		
      <form action = "" method = "post">
         <table summary = "">
            <tr>
               <th><label for = " username">Your name:</label></th>
               <td><input type = " text" id = " username" name = " username" /></td>
            </tr>
				
            <tr>
               <th><label for = " url">Link URL:</label></th>
               <td><input type = " text" id=" url" name= " url" /></td>
            </tr>
				
            <tr>
               <th><label for = " title">Title:</label></th>
               <td><input type = " text" name = " title" /></td>
            </tr>
				
            <tr>
               <td></td>
               <td>
                  <input type = " submit" value = " Submit" />
                  <input type = " submit" name = " cancel" value = "Cancel" />
               </td>
            </tr>
				
         </table>
			
      </form>
      <div id = "footer">
      </div>
		
   </body>
	
</html>

Step 10 - Otrzymasz następujący wynik -

Tutaj nazwa metody jest zdefiniowana jako „POST”. Zawsze ważne jest, aby zweryfikować metodę określoną w pliku. Jeżeli metoda obejmuje metodę „POST”, wartości należy ponownie sprawdzić w bazie danych w odpowiednich polach.

Jeśli metoda zawiera metodę „GET”, wartości do zapisania będą widoczne w adresie URL.

Usługa internetowa to zestaw komponentów internetowych, który pomaga w wymianie danych między aplikacją lub systemami, który obejmuje również otwarte protokoły i standardy. Można je publikować, wykorzystywać i znajdować w sieci.

Usługi sieciowe są różnego typu, takie jak RWS (RESTfUL Web Service), WSDL, SOAP i wiele innych.

REST - Reprezentacyjny transfer państwa

Typ protokołu zdalnego dostępu, który przesyła stan z klienta do serwera, który może służyć do manipulowania stanem zamiast wywoływania procedur zdalnych.

  • Nie definiuje żadnego konkretnego kodowania ani struktury ani sposobów zwracania przydatnych komunikatów o błędach.

  • Używa „czasowników” HTTP do wykonywania operacji transferu stanu.

  • Zasoby są jednoznacznie identyfikowane za pomocą adresu URL.

  • Nie jest to API, ale warstwa transportowa API.

REST utrzymuje nazewnictwo zasobów w sieci i zapewnia jednolity mechanizm wykonywania operacji na tych zasobach. Każdy zasób jest identyfikowany przez co najmniej jeden identyfikator. Jeśli infrastruktura REST jest zaimplementowana w oparciu o protokół HTTP, wówczas te identyfikatory są określane jakoUniform Resource Identifiers (URIs).

Poniżej przedstawiono dwa wspólne podzbiory zestawu URI -

Podzbiór Pełna forma Przykład
URL Uniform Resource Locator http://www.gmail.com/
URNA Jednolita nazwa zasobu urn: isbn: 0-201-71088-9 urn: uuid: 13e8cf26-2a25-11db-8693-000ae4ea7d46

Zanim zrozumiemy implementację architektury CherryPy, skupmy się na architekturze CherryPy.

CherryPy zawiera następujące trzy składniki -

  • cherrypy.engine - Kontroluje uruchamianie / kończenie procesów i obsługę zdarzeń.

  • cherrypy.server - Konfiguruje i steruje serwerem WSGI lub HTTP.

  • cherrypy.tools - Zestaw narzędzi, które są ortogonalne do przetwarzania żądania HTTP.

Interfejs REST przez CherryPy

Usługa sieciowa RESTful implementuje każdą sekcję architektury CherryPy za pomocą następujących elementów -

  • Authentication
  • Authorization
  • Structure
  • Encapsulation
  • Obsługa błędów

Poświadczenie

Uwierzytelnianie pomaga w weryfikacji użytkowników, z którymi się kontaktujemy. CherryPy zawiera narzędzia do obsługi każdej metody uwierzytelniania.

def authenticate():
   if not hasattr(cherrypy.request, 'user') or cherrypy.request.user is None:
      # < Do stuff to look up your users >
		
      cherrypy.request.authorized = False # This only authenticates. 
         Authz must be handled separately.
		
      cherrypy.request.unauthorized_reasons = []
      cherrypy.request.authorization_queries = []
		
cherrypy.tools.authenticate = \
   cherrypy.Tool('before_handler', authenticate, priority=10)

Powyższa funkcja authentication () pomoże zweryfikować istnienie klientów lub użytkowników. Wbudowane narzędzia pomagają w systematycznej realizacji procesu.

Upoważnienie

Autoryzacja pomaga w utrzymaniu prawidłowości procesu za pośrednictwem identyfikatora URI. Ten proces pomaga również w morfowaniu obiektów przez leady tokena użytkownika.

def authorize_all():
   cherrypy.request.authorized = 'authorize_all'
	
cherrypy.tools.authorize_all = cherrypy.Tool('before_handler', authorize_all, priority=11)

def is_authorized():
   if not cherrypy.request.authorized:
      raise cherrypy.HTTPError("403 Forbidden",
         ','.join(cherrypy.request.unauthorized_reasons))
			
cherrypy.tools.is_authorized = cherrypy.Tool('before_handler', is_authorized, 
priority = 49)

cherrypy.config.update({
   'tools.is_authorized.on': True,
   'tools.authorize_all.on': True
})

Wbudowane narzędzia autoryzacji pomagają w systematycznej obsłudze procedur, o czym wspomniano w poprzednim przykładzie.

Struktura

Utrzymanie struktury API pomaga zmniejszyć obciążenie pracą związaną z mapowaniem URI aplikacji. Zawsze konieczne jest, aby API było wykrywalne i czyste. Podstawowa struktura API dla platformy CherryPy powinna mieć następujące cechy -

  • Konta i użytkownik
  • Autoresponder
  • Contact
  • File
  • Folder
  • Lista i pole
  • Wiadomość i partia

Kapsułkowanie

Hermetyzacja pomaga w tworzeniu interfejsu API, który jest lekki, czytelny dla człowieka i dostępny dla różnych klientów. Lista elementów wraz z tworzeniem, pobieraniem, aktualizacją i usuwaniem wymaga hermetyzacji API.

Obsługa błędów

Ten proces zarządza błędami, jeśli występują, jeśli API nie działa zgodnie z określonym instynktem. Na przykład 400 oznacza błędne żądanie, a 403 oznacza nieautoryzowane żądanie.

Przykład

Rozważmy następujące przykłady błędów bazy danych, walidacji lub aplikacji.

import cherrypy
import json

def error_page_default(status, message, traceback, version):
   ret = {
      'status': status,
      'version': version,
      'message': [message],
      'traceback': traceback
   }
	
   return json.dumps(ret)
	
class Root:
   _cp_config = {'error_page.default': error_page_default}
	
@cherrypy.expose
   def index(self):
      raise cherrypy.HTTPError(500, "Internal Sever Error")
cherrypy.quickstart(Root())

Powyższy kod wygeneruje następujący wynik -

Zarządzanie interfejsem API (interfejs programowania aplikacji) jest łatwe dzięki CherryPy dzięki wbudowanym narzędziom dostępowym.

Metody HTTP

Lista metod HTTP, które działają na zasobach, jest następująca -

S.Nr Metoda i działanie HTTP
1.

HEAD

Pobiera metadane zasobów.

2.

GET

Pobiera metadane i zawartość zasobów.

3.

POST

Żąda od serwera utworzenia nowego zasobu przy użyciu danych zawartych w treści żądania.

4.

PUT

Żąda od serwera zastąpienia istniejącego zasobu zasobem zawartym w treści żądania.

5.

DELETE

Żąda od serwera usunięcia zasobu zidentyfikowanego przez ten identyfikator URI.

6.

OPTIONS

Żąda od serwera, aby zwrócił szczegółowe informacje o możliwościach globalnie lub konkretnie w odniesieniu do zasobu.

Protokół publikowania Atom (APP)

APP wywodzi się ze społeczności Atom jako protokół na poziomie aplikacji, będący uzupełnieniem protokołu HTTP, umożliwiający publikowanie i edycję zasobów internetowych. Jednostka komunikatów między serwerem APP a klientem jest oparta na formacie dokumentu XML Atom.

Protokół Atom Publishing Protocol definiuje zestaw operacji między usługą APP a agentem użytkownika przy użyciu protokołu HTTP i jego mechanizmów oraz formatu dokumentu XML Atom jako jednostki komunikatów.

APP najpierw definiuje dokument serwisowy, który dostarcza agentowi użytkownika identyfikatory URI różnych kolekcji obsługiwanych przez usługę APP.

Przykład

Weźmy przykład, aby pokazać, jak działa APP -

<?xml version = "1.0" encoding = "UTF-8"?>
<service xmlns = "http://purl.org/atom/app#" xmlns:atom = "http://www.w3.org/2005/Atom">
   
   <workspace>
      <collection href = "http://host/service/atompub/album/">
         <atom:title> Albums</atom:title>
         <categories fixed = "yes">
            <atom:category term = "friends" />
         </categories>
      </collection>
      
      <collection href = "http://host/service/atompub/film/">
         <atom:title>Films</atom:title>
         <accept>image/png,image/jpeg</accept>
      </collection>
   </workspace>
	
</service>

APP określa sposób wykonywania podstawowych operacji CRUD względem elementu członkowskiego kolekcji lub samej kolekcji przy użyciu metod HTTP zgodnie z opisem w poniższej tabeli -

Operacja Metoda HTTP Kod statusu Zadowolony
Odzyskać DOSTAĆ 200 Wpis Atom reprezentujący zasób
Stwórz POCZTA 201 Identyfikator URI nowo utworzonego zasobu za pośrednictwem nagłówków Location i Content-Location
Aktualizacja POŁOŻYĆ 200 Wpis Atom reprezentujący zasób
Usunąć USUNĄĆ 200 Żaden

Warstwa prezentacji zapewnia, że ​​przechodząca przez nią komunikacja jest skierowana do zamierzonych odbiorców. CherryPy utrzymuje działanie warstwy prezentacji przez różne silniki szablonów.

Silnik szablonów przyjmuje dane wejściowe strony za pomocą logiki biznesowej, a następnie przetwarza je na ostateczną stronę, która jest przeznaczona tylko dla zamierzonych odbiorców.

Kid - silnik szablonów

Kid to prosty silnik szablonów, który zawiera nazwę szablonu do przetworzenia (co jest obowiązkowe) oraz dane wejściowe do przekazania podczas renderowania szablonu.

Podczas tworzenia szablonu po raz pierwszy Kid tworzy moduł Pythona, który może służyć jako buforowana wersja szablonu.

Plik kid.Template funkcja zwraca instancję klasy szablonu, której można użyć do renderowania treści wyjściowej.

Klasa szablonu zawiera następujący zestaw poleceń -

S.Nr Polecenie i opis
1.

serialize

Zwraca zawartość wyjściową jako ciąg.

2.

generate

Zwraca zawartość wyjściową jako iterator.

3.

write

Zrzuca zawartość wyjściową do obiektu pliku.

Parametry używane przez te polecenia są następujące -

S.Nr Polecenie i opis
1.

encoding

Informuje, jak zakodować zawartość wyjściową

2.

fragment

Jest to wartość logiczna, która mówi prologowi XML lub Doctype

3.

output

Ten typ serializacji jest używany do renderowania zawartości

Przykład

Weźmy przykład, aby zrozumieć, jak to zrobić kid działa -

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns:py = "http://purl.org/kid/ns#">
   <head>
      <title>${title}</title> <link rel = "stylesheet" href = "style.css" /> </head> <body> <p>${message}</p>
   </body>
</html>

The next step after saving the file is to process the template via the Kid engine.

import kid

params = {'title': 'Hello world!!', 'message': 'CherryPy.'}
t = kid.Template('helloworld.kid', **params)
print t.serialize(output='html')

Atrybuty dzieci

Oto atrybuty Kid -

Język szablonów oparty na języku XML

Jest to język oparty na XML. Szablon Kid musi być dobrze sformułowanym dokumentem XML z odpowiednimi konwencjami nazewnictwa.

Kid implementuje atrybuty w elementach XML, aby zaktualizować bazowy silnik w akcji, która ma być wykonana w celu osiągnięcia elementu. Aby uniknąć nakładania się z innymi istniejącymi atrybutami w dokumencie XML, Kid wprowadził własną przestrzeń nazw.

<p py:if = "...">...</p>

Zastępowanie zmiennych

Kid ma schemat podstawiania zmiennych i proste podejście - $ {nazwa-zmiennej}.

Zmienne mogą być używane w atrybutach elementów lub jako zawartość tekstowa elementu. Dziecko będzie oceniać zmienną za każdym razem, gdy ma miejsce wykonanie.

Jeśli użytkownik potrzebuje wyjścia ciągu literału jako $ {coś}, można go zmienić za pomocą podstawienia zmiennej przez podwojenie znaku dolara.

Instrukcja warunkowa

Do przełączania różnych przypadków w szablonie używana jest następująca składnia -

<tag py:if = "expression">...</tag>

Tutaj tag to nazwa elementu, na przykład DIV lub SPAN.

Wyrażenie jest wyrażeniem Pythona. Jeśli jako wartość logiczna przyjmuje wartość True, element zostanie uwzględniony w treści wyjściowej lub nie będzie częścią zawartości wyjściowej.

Mechanizm pętli

Do zapętlenia elementu w Kid, używana jest następująca składnia -

<tag py:for = "expression">...</tag>

Tutaj tag to nazwa elementu. Wyrażenie jest wyrażeniem Pythona, na przykład dla wartości w [...].

Przykład

Poniższy kod pokazuje, jak działa mechanizm zapętlenia -

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
   <head>
      <title>${title}</title> <link rel = "stylesheet" href = "style.css" /> </head> <body> <table> <caption>A few songs</caption> <tr> <th>Artist</th> <th>Album</th> <th>Title</th> </tr> <tr py:for = "info in infos"> <td>${info['artist']}</td>
            <td>${info['album']}</td> <td>${info['song']}</td>
         </tr>
      </table>
   </body>
</html>

import kid

params = discography.retrieve_songs()
t = kid.Template('songs.kid', **params)
print t.serialize(output='html')

Plik output dla powyższego kodu z mechanizmem zapętlenia wygląda następująco -

Do 2005 roku wzorcem we wszystkich aplikacjach internetowych było zarządzanie jednym żądaniem HTTP na stronę. Przejście z jednej strony na inną wymagało załadowania całej strony. Zmniejszyłoby to wydajność na wyższym poziomie.

Tak więc nastąpił wzrost rich client applications który kiedyś osadzał z nimi AJAX, XML i JSON.

AJAX

Asynchroniczny JavaScript i XML (AJAX) to technika tworzenia szybkich i dynamicznych stron internetowych. AJAX umożliwia asynchroniczne aktualizowanie stron internetowych poprzez wymianę niewielkich ilości danych za kulisami z serwerem. Oznacza to, że możliwa jest aktualizacja części strony internetowej bez przeładowywania całej strony.

Mapy Google, Gmail, YouTube i Facebook to kilka przykładów aplikacji AJAX.

Ajax opiera się na pomyśle wysyłania żądań HTTP przy użyciu JavaScript; w szczególności AJAX polega na obiekcie XMLHttpRequest i jego API do wykonywania tych operacji.

JSON

JSON to sposób na przenoszenie zserializowanych obiektów JavaScript w taki sposób, aby aplikacja JavaScript mogła je ocenić i przekształcić w obiekty JavaScript, którymi można później manipulować.

Na przykład, gdy użytkownik zażąda od serwera obiektu albumu sformatowanego w formacie JSON, serwer zwróci dane wyjściowe w następujący sposób -

{'description': 'This is a simple demo album for you to test', 'author': ‘xyz’}

Teraz dane są tablicą asocjacyjną JavaScript, a dostęp do pola opisu można uzyskać za pośrednictwem -

data ['description'];

Zastosowanie AJAX do aplikacji

Rozważ aplikację, która zawiera folder o nazwie „media” z wtyczką index.html i Jquery oraz plik z implementacją AJAX. Rozważmy nazwę pliku jako „ajax_app.py”

ajax_app.py

import cherrypy
import webbrowser
import os
import simplejson
import sys

MEDIA_DIR = os.path.join(os.path.abspath("."), u"media")

class AjaxApp(object):
   @cherrypy.expose
   def index(self):
      return open(os.path.join(MEDIA_DIR, u'index.html'))

   @cherrypy.expose
   def submit(self, name):
      cherrypy.response.headers['Content-Type'] = 'application/json'
      return simplejson.dumps(dict(title="Hello, %s" % name))
		
config = {'/media':
   {'tools.staticdir.on': True,
   'tools.staticdir.dir': MEDIA_DIR,}
}
			
def open_page():
webbrowser.open("http://127.0.0.1:8080/")
cherrypy.engine.subscribe('start', open_page)
cherrypy.tree.mount(AjaxApp(), '/', config=config)
cherrypy.engine.start()

Klasa „AjaxApp” przekierowuje do strony internetowej „index.html”, która znajduje się w folderze multimediów.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
   " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
	
<html xmlns = "http://www.w3.org/1999/xhtml" lang = "en" xml:lang = "en">
   <head>
      <title>AJAX with jQuery and cherrypy</title>
      <meta http-equiv = " Content-Type" content = " text/html; charset=utf-8" />
      <script type = " text/javascript" src = " /media/jquery-1.4.2.min.js"></script>
		
      <script type = " text/javascript">
         $(function() { // When the testform is submitted... $("#formtest").submit(function() {
         
               // post the form values via AJAX...
               $.post('/submit', {name: $("#name").val()}, function(data) {
         
                  // and set the title with the result
                  $("#title").html(data['title']) ;
               });
               return false ;
            });
         });
      </script>
		
   </head>
	
   <body>
      <h1 id = "title">What's your name?</h1>
      <form id = " formtest" action = " #" method = " post">
         <p>
            <label for = " name">Name:</label>
            <input type = " text" id = "name" /> <br />
            <input type = " submit" value = " Set" />
         </p>
      </form>
   </body>
	
</html>

Funkcja AJAX jest zawarta w tagach <script>.

Wynik

Powyższy kod wygeneruje następujący wynik -

Po przesłaniu wartości przez użytkownika zaimplementowana zostaje funkcjonalność AJAX, a ekran zostaje przekierowany do formularza, jak pokazano poniżej -

W tym rozdziale skupimy się na tworzeniu aplikacji we frameworku CherryPy.

Rozważać Photoblogaplikacja do demo aplikacji CherryPy. Aplikacja Photoblog to zwykły blog, ale głównym tekstem będą zdjęcia zamiast tekstu. Głównym haczykiem aplikacji Photoblog jest to, że programista może bardziej skupić się na projektowaniu i wdrażaniu.

Struktura podstawowa - projektowanie jednostek

Podmioty projektują podstawową strukturę aplikacji. Poniżej przedstawiono jednostki dla aplikacji Photoblog -

  • Film
  • Photo
  • Album

Poniżej znajduje się podstawowy diagram klas dla relacji encji -

Struktura projektu

Jak omówiono w poprzednim rozdziale, struktura projektowa projektu wyglądałaby tak, jak pokazano na poniższym zrzucie ekranu -

Rozważ daną aplikację, która ma podkatalogi dla aplikacji Photoblog. Podkatalogi to Photo, Album i Film, które obejmują controllers.py, models.py i server.py.

Funkcjonalnie aplikacja Photoblog zapewni interfejsy API do manipulowania tymi jednostkami za pośrednictwem tradycyjnego interfejsu CRUD - tworzenia, pobierania, aktualizowania i usuwania.

Połączenie z bazą danych

Moduł pamięci zawiera zestaw operacji; połączenie z bazą danych będącą jedną z operacji.

Ponieważ jest to kompletna aplikacja, połączenie z bazą danych jest obowiązkowe dla API i dla zachowania funkcjonalności tworzenia, pobierania, aktualizacji i usuwania.

import dejavu

arena = dejavu.Arena()
from model import Album, Film, Photo
def connect():

conf = {'Connect': "host=localhost dbname=Photoblog user=test password=test"}
arena.add_store("main", "postgres", conf)
arena.register_all(globals())

Arena w powyższym kodzie będzie naszym interfejsem między podstawowym menedżerem pamięci a warstwą logiki biznesowej.

Funkcja connect dodaje menedżera pamięci do obiektu arena dla RDBMS PostgreSQL.

Po uzyskaniu połączenia możemy tworzyć formularze zgodnie z wymaganiami biznesowymi i zakończyć pracę aplikacji.

Najważniejszą rzeczą przed stworzeniem jakiejkolwiek aplikacji jest entity mapping i zaprojektowanie struktury aplikacji.

Testowanie to proces, podczas którego aplikacja jest prowadzona z różnych perspektyw w celu -

  • Znajdź listę problemów
  • Znajdź różnice między oczekiwanym a rzeczywistym wynikiem, wynikiem, stanami itp.
  • Zrozum etap wdrażania.
  • Znajdź aplikację przydatną do realistycznych celów.

Celem testowania nie jest spowodowanie winy programisty, ale zapewnienie narzędzi i poprawienie jakości do oszacowania kondycji aplikacji w określonym czasie.

Testowanie należy zaplanować z wyprzedzeniem. Wymaga to zdefiniowania celu testowania, zrozumienia zakresu przypadków testowych, sporządzenia listy wymagań biznesowych i świadomości ryzyka związanego z różnymi fazami projektu.

Testowanie definiuje się jako szereg aspektów, które należy zweryfikować w systemie lub aplikacji. Poniżej znajduje się lista plikówcommon test approaches -

  • Unit testing- Zwykle robią to sami programiści. Ma to na celu sprawdzenie, czy jednostka kodu działa zgodnie z oczekiwaniami, czy nie.

  • Usability testing- Deweloperzy zwykle zapominają, że piszą aplikację dla użytkowników końcowych, którzy nie mają wiedzy o systemie. Testy użyteczności weryfikują zalety i wady produktu.

  • Functional/Acceptance testing - Podczas gdy testy użyteczności sprawdzają, czy aplikacja lub system nadaje się do użytku, testy funkcjonalne zapewniają zaimplementowanie każdej określonej funkcjonalności.

  • Load and performance testing- Ma to na celu zrozumienie, czy system może dostosować się do przeprowadzanych testów obciążenia i wydajności. Może to prowadzić do zmian w sprzęcie, optymalizacji zapytań SQL itp.

  • Regression testing - Sprawdza, czy kolejne wydania produktu nie przerywają żadnej z wcześniejszych funkcjonalności.

  • Reliability and resilience testing - Testowanie niezawodności pomaga w walidacji aplikacji systemowej z awariami jednego lub kilku komponentów.

Testów jednostkowych

Aplikacje fotoblogów stale używają testów jednostkowych, aby sprawdzić następujące elementy -

  • Nowe funkcjonalności działają poprawnie i zgodnie z oczekiwaniami.
  • Istniejące funkcjonalności nie są przerywane przez nowe wydanie kodu.
  • Usterki są naprawiane i pozostają naprawione.

Python jest dostarczany ze standardowym modułem unittest oferującym inne podejście do testów jednostkowych.

Unittest

unittest jest zakorzeniony w JUnit, pakiecie testów jednostkowych Java opracowanym przez Kenta Becka i Ericha Gamma. Testy jednostkowe po prostu zwracają zdefiniowane dane. Można zdefiniować pozorowane obiekty. Obiekty te umożliwiają testowanie w interfejsie naszego projektu bez konieczności polegania na całej aplikacji. Umożliwiają również uruchamianie testów w trybie izolacji wraz z innymi testami.

Zdefiniujmy atrapę klasy w następujący sposób -

import unittest

class DummyTest(unittest.TestCase):
def test_01_forward(self):
dummy = Dummy(right_boundary=3)
   self.assertEqual(dummy.forward(), 1)
   self.assertEqual(dummy.forward(), 2)
   self.assertEqual(dummy.forward(), 3)
   self.assertRaises(ValueError, dummy.forward)

def test_02_backward(self):
dummy = Dummy(left_boundary=-3, allow_negative=True)
   self.assertEqual(dummy.backward(), -1)
   self.assertEqual(dummy.backward(), -2)
   self.assertEqual(dummy.backward(), -3)
   self.assertRaises(ValueError, dummy.backward)

def test_03_boundaries(self):
dummy = Dummy(right_boundary=3, left_boundary=-3,allow_negative=True)
   self.assertEqual(dummy.backward(), -1)
   self.assertEqual(dummy.backward(), -2)
   self.assertEqual(dummy.forward(), -1)
   self.assertEqual(dummy.backward(), -2)
   self.assertEqual(dummy.backward(), -3)

Wyjaśnienie kodu jest następujące -

  • Należy zaimportować moduł unittest, aby zapewnić możliwości testów jednostkowych dla danej klasy.

  • Klasę należy utworzyć przez podklasę unittest.

  • Każda metoda w powyższym kodzie zaczyna się od testu słów. Wszystkie te metody są wywoływane przez procedurę obsługi unittest.

  • Metody assert / fail są wywoływane przez przypadek testowy w celu zarządzania wyjątkami.

Rozważ to jako przykład do uruchomienia przypadku testowego -

if __name__ == '__main__':
unittest.main()

Wynik (dane wyjściowe) uruchomienia przypadku testowego będzie następujący -

----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK

Testy funkcjonalności

Gdy funkcje aplikacji zaczną nabierać kształtu zgodnie z wymaganiami, zestaw testów funkcjonalnych może zweryfikować poprawność aplikacji w zakresie specyfikacji. Jednak test powinien zostać zautomatyzowany, aby uzyskać lepszą wydajność, co wymagałoby użycia produktów innych firm, takich jak Selenium.

CherryPy zapewnia klasę pomocniczą, taką jak wbudowane funkcje, które ułatwiają pisanie testów funkcjonalnych.

Testowanie obciążenia

W zależności od aplikacji, którą piszesz i Twoich oczekiwań co do wielkości, może być konieczne przeprowadzenie testów obciążenia i wydajności w celu wykrycia potencjalnych wąskich gardeł w aplikacji, które uniemożliwiają jej osiągnięcie określonego poziomu wydajności.

Ta sekcja nie będzie szczegółowo opisywać, jak przeprowadzić test wydajności lub obciążenia, ponieważ jest poza pakietem FunkLoad.

Bardzo podstawowy przykład FunkLoad jest następujący -

from funkload.FunkLoadTestCase 
import FunkLoadTestCase

class LoadHomePage(FunkLoadTestCase):
def test_homepage(self):

server_url = self.conf_get('main', 'url')
nb_time = self.conf_getInt('test_homepage', 'nb_time')
home_page = "%s/" % server_url

for i in range(nb_time):
self.logd('Try %i' % i)
self.get(home_page, description='Get gome page')
if __name__ in ('main', '__main__'):

import unittest

unittest.main()

Oto szczegółowe wyjaśnienie powyższego kodu -

  • Przypadek testowy musi dziedziczyć po klasie FunkLoadTestCase, aby funkcja FunkLoad mogła wykonać swoje wewnętrzne zadanie śledzenia tego, co dzieje się podczas testu.

  • Nazwa klasy jest ważna, ponieważ FunkLoad będzie szukał pliku na podstawie nazwy klasy.

  • Zaprojektowane przypadki testowe mają bezpośredni dostęp do plików konfiguracyjnych. Metody Get () i post () są po prostu wywoływane na serwerze w celu uzyskania odpowiedzi.

W tym rozdziale skupimy się bardziej na aplikacji SSL opartej na CherryPy, włączonej przez wbudowany serwer HTTP CherryPy.

Konfiguracja

Istnieją różne poziomy ustawień konfiguracji wymaganych w aplikacji internetowej -

  • Web server - Ustawienia powiązane z serwerem HTTP

  • Engine - Ustawienia związane z hostingiem silnika

  • Application - Aplikacja, z której korzysta użytkownik

Rozlokowanie

Wdrożenie aplikacji CherryPy jest uważane za dość prostą metodę, w której wszystkie wymagane pakiety są dostępne ze ścieżki systemowej Pythona. We współużytkowanym środowisku hostowanym w sieci Web serwer sieciowy będzie znajdował się w interfejsie użytkownika, co umożliwia dostawcy hosta wykonywanie działań filtrowania. Serwer frontonu może być serwerem Apache lublighttpd.

Ta sekcja przedstawia kilka rozwiązań do uruchamiania aplikacji CherryPy za serwerami WWW Apache i lighttpd.

cherrypy
def setup_app():

class Root:
@cherrypy.expose
def index(self):
   # Return the hostname used by CherryPy and the remote
   # caller IP address
	
return "Hello there %s from IP: %s " %
(cherrypy.request.base, cherrypy.request.remote.ip)
cherrypy.config.update({'server.socket_port': 9091,
   'environment': 'production',
   'log.screen': False,
   'show_tracebacks': False})
	
cherrypy.tree.mount(Root())
if __name__ == '__main__':

setup_app()
cherrypy.server.quickstart()
cherrypy.engine.start()

SSL

SSL (Secure Sockets Layer)może być obsługiwany w aplikacjach opartych na CherryPy. Aby włączyć obsługę SSL, muszą być spełnione następujące wymagania -

  • Zainstaluj pakiet PyOpenSSL w środowisku użytkownika
  • Posiadaj certyfikat SSL i klucz prywatny na serwerze

Tworzenie certyfikatu i klucza prywatnego

Zajmijmy się wymaganiami certyfikatu i klucza prywatnego -

  • Najpierw użytkownik potrzebuje klucza prywatnego -
openssl genrsa -out server.key 2048
  • Ten klucz nie jest chroniony hasłem i dlatego ma słabą ochronę.
  • Zostanie wydane następujące polecenie -
openssl genrsa -des3 -out server.key 2048
  • Program będzie wymagał hasła. Jeśli Twoja wersja OpenSSL umożliwia podanie pustego ciągu, zrób to. W przeciwnym razie wprowadź domyślne hasło, a następnie usuń je z wygenerowanego klucza w następujący sposób -

openssl rsa -in server.key -out server.key
  • Utworzenie certyfikatu wygląda następująco -
openssl req -new -key server.key -out server.csr
  • Ten proces wymaga podania pewnych szczegółów. Aby to zrobić, należy wydać następujące polecenie -

openssl x509 -req -days 60 -in server.csr -signkey
server.key -out server.crt
  • Nowo podpisany certyfikat będzie ważny przez 60 dni.

Poniższy kod przedstawia jego implementację -

import cherrypy
import os, os.path

localDir = os.path.abspath(os.path.dirname(__file__))
CA = os.path.join(localDir, 'server.crt')
KEY = os.path.join(localDir, 'server.key')
def setup_server():

class Root:
@cherrypy.expose
def index(self):
   return "Hello there!"
	
cherrypy.tree.mount(Root())
if __name__ == '__main__':

setup_server()
cherrypy.config.update({'server.socket_port': 8443,
   'environment': 'production',
   'log.screen': True,
   'server.ssl_certificate': CA,
   'server.ssl_private_key': KEY})
	
cherrypy.server.quickstart()
cherrypy.engine.start()

Następnym krokiem jest uruchomienie serwera; jeśli ci się powiedzie, na ekranie zobaczysz następujący komunikat -

HTTP Serving HTTPS on https://localhost:8443/