CherryPy - Guida rapida

CherryPy è un framework web di Python che fornisce un'interfaccia amichevole al protocollo HTTP per gli sviluppatori Python. Viene anche chiamata libreria di applicazioni Web.

CherryPy utilizza i punti di forza di Python come linguaggio dinamico per modellare e associare il protocollo HTTP a un'API. È uno dei più vecchi framework web per Python, che fornisce un'interfaccia pulita e una piattaforma affidabile.

Storia di CherryPy

Remi Delon ha rilasciato la prima versione di CherryPy alla fine di giugno 2002. Questo è stato il punto di partenza di una libreria web Python di successo. Remi è un hacker francese che si è fidato di Python per essere una delle migliori alternative per lo sviluppo di applicazioni web.

Il progetto sviluppato da Remi ha attratto un numero di sviluppatori interessati all'approccio. L'approccio includeva le seguenti caratteristiche:

  • CherryPy era vicino al pattern model-view-controller.

  • Una classe CherryPy deve essere elaborata e compilata dal motore CherryPy per produrre un modulo Python autonomo che incorpora l'applicazione completa e anche il proprio server web integrato.

  • CherryPy può mappare un URL e la sua stringa di query in una chiamata al metodo Python, ad esempio:

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

Durante i due anni di sviluppo nel progetto CherryPy, è stato supportato dalla comunità e Remi ha rilasciato diverse versioni migliorate.

Nel giugno 2004 è iniziata una discussione sul futuro del progetto e se debba continuare con la stessa architettura. Il brainstorming e la discussione di diversi clienti abituali del progetto hanno poi portato al concetto di motore e filtri per la pubblicazione di oggetti, che presto sono diventati una parte fondamentale di CherryPy2. Successivamente, nell'ottobre 2004, è stata rilasciata la prima versione di CherryPy 2 alpha come prova del concetto di queste idee fondamentali. CherryPy 2.0 è stato un vero successo; tuttavia, è stato riconosciuto che il suo design poteva ancora essere migliorato e necessitava di refactoring.

Dopo discussioni basate sui feedback, l'API di CherryPy è stata ulteriormente modificata per migliorarne l'eleganza, portando al rilascio di CherryPy 2.1.0 nell'ottobre 2005. Dopo varie modifiche, il team ha rilasciato CherryPy 2.2.0 nell'aprile 2006.

Punti di forza di CherryPy

Le seguenti caratteristiche di CherryPy sono considerate i suoi punti di forza:

Semplicità

Sviluppare un progetto in CherryPy è un compito semplice con poche righe di codice sviluppato secondo le convenzioni e le indentazioni di Python.

CherryPy è anche molto modulare. I componenti primari sono ben gestiti con un concetto logico corretto e le classi padre sono espandibili in classi figlie.

Energia

CherryPy sfrutta tutta la potenza di Python. Fornisce inoltre strumenti e plug-in, che sono potenti punti di estensione necessari per sviluppare applicazioni di livello mondiale.

Open source

CherryPy è un framework Web Python open source (concesso in licenza con licenza BSD open source), il che significa che questo framework può essere utilizzato commercialmente a costo ZERO.

Aiuto della comunità

Ha una comunità devota che fornisce supporto completo con vari tipi di domande e risposte. La community cerca di fornire assistenza completa agli sviluppatori partendo dal livello principiante fino al livello avanzato.

Distribuzione

Esistono modi convenienti per distribuire l'applicazione. CherryPy include il proprio server HTTP pronto per la produzione per ospitare la tua applicazione. CherryPy può anche essere distribuito su qualsiasi gateway conforme a WSGI.

CherryPy è disponibile in pacchetti come la maggior parte dei progetti open source, che possono essere scaricati e installati in vari modi che sono menzionati come segue:

  • Utilizzando un Tarball
  • Utilizzando easy_install
  • Usare Subversion

Requisiti

I requisiti di base per l'installazione del framework CherryPy includono:

  • Python con versione 2.4 o successiva
  • CherryPy 3.0

L'installazione di un modulo Python è considerato un processo facile. L'installazione include l'uso dei seguenti comandi.

python setup.py build
python setup.py install

I pacchetti di Python sono archiviati nelle seguenti directory predefinite:

  • Su UNIX o Linux,
/usr/local/lib/python2.4/site-packages
or
/usr/lib/python2.4/site-packages
  • Su Microsoft Windows,
C:\Python or C:\Python2x
  • In Mac OS,
Python:Lib:site-package

Installazione tramite Tarball

Un Tarball è un archivio compresso di file o una directory. Il framework CherryPy fornisce un Tarball per ciascuna delle sue versioni (alpha, beta e stabile).

Contiene il codice sorgente completo della libreria. Il nome deriva dall'utilità utilizzata in UNIX e altri sistemi operativi.

Ecco i passaggi da seguire per l'installazione di CherryPy utilizzando tar ball -

Step 1 - Scarica la versione secondo i requisiti dell'utente da http://download.cherrypy.org/

Step 2- Cerca la directory in cui è stato scaricato Tarball e decomprimilo. Per il sistema operativo Linux, digita il seguente comando:

tar zxvf cherrypy-x.y.z.tgz

Per Microsoft Windows, l'utente può utilizzare un'utilità come 7-Zip o Winzip per decomprimere l'archivio tramite un'interfaccia grafica.

Step 3 - Spostati nella directory appena creata e usa il seguente comando per compilare CherryPy -

python setup.py build

Per l'installazione globale, è necessario utilizzare il seguente comando:

python setup.py install

Installazione utilizzando easy_install

Python Enterprise Application Kit (PEAK) fornisce un modulo python denominato Easy Install. Ciò facilita la distribuzione dei pacchetti Python. Questo modulo semplifica la procedura di download, creazione e distribuzione di applicazioni e prodotti Python.

Easy Install deve essere installato nel sistema prima di installare CherryPy.

Step 1 - Scarica il modulo ez_setup.py da http://peak.telecommunity.com ed eseguilo utilizzando i diritti di amministratore sul computer: python ez_setup.py.

Step 2 - Il seguente comando viene utilizzato per installare Easy Install.

easy_install product_name

Step 3- easy_install cercherà nell'indice dei pacchetti Python (PyPI) per trovare il prodotto specificato. PyPI è un archivio centralizzato di informazioni per tutti i prodotti Python.

Usa il seguente comando per distribuire l'ultima versione disponibile di CherryPy:

easy_install cherrypy

Step 4 - easy_install scaricherà CherryPy, lo compilerà e lo installerà globalmente nel tuo ambiente Python.

Installazione tramite Subversion

L'installazione di CherryPy utilizzando Subversion è consigliata nelle seguenti situazioni:

  • Esiste una funzionalità o è stato corretto un bug ed è disponibile solo nel codice in fase di sviluppo.

  • Quando lo sviluppatore lavora su CherryPy stesso.

  • Quando l'utente necessita di un ramo dal ramo principale nel repository di controllo delle versioni.

  • Per la correzione dei bug della versione precedente.

Il principio di base del sovversione è registrare un repository e tenere traccia di ciascuna delle versioni, che includono una serie di modifiche in esse.

Segui questi passaggi per comprendere l'installazione di CherryPy utilizzando Subversion

Step 1 - Per utilizzare la versione più recente del progetto, è necessario controllare la cartella del trunk che si trova nel repository di Subversion.

Step 2 - Immettere il seguente comando da una shell -

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

Step 3 - Ora, crea una directory CherryPy e scarica il codice sorgente completo al suo interno.

Verifica dell'installazione

È necessario verificare se l'applicazione è stata installata correttamente nel sistema o meno nello stesso modo in cui si fa per applicazioni come Java.

È possibile scegliere uno qualsiasi dei tre metodi menzionati nel capitolo precedente per installare e distribuire CherryPy nel proprio ambiente. CherryPy deve essere in grado di importare dalla shell Python come segue:

import cherrypy

cherrypy.__version__
'3.0.0'

Se CherryPy non è installato globalmente nell'ambiente Python del sistema locale, è necessario impostare la variabile d'ambiente PYTHONPATH, altrimenti verrà visualizzato un errore nel modo seguente:

import cherrypy

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

Ci sono alcune importanti parole chiave che devono essere definite per comprendere il funzionamento di CherryPy. Le parole chiave e le definizioni sono le seguenti:

S.No Parola chiave e definizione
1.

Web Server

È un'interfaccia che si occupa del protocollo HTTP. Il suo obiettivo è trasformare le richieste HTTP nel server delle applicazioni in modo che ottengano le risposte.

2.

Application

È un software che raccoglie informazioni.

3.

Application server

È il componente che contiene una o più applicazioni

4.

Web application server

È la combinazione di server Web e server applicazioni.

Esempio

L'esempio seguente mostra un codice di esempio di CherryPy:

import cherrypy

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

Vediamo ora come funziona il codice -

  • Il pacchetto denominato CherryPy viene sempre importato nella classe specificata per garantire il corretto funzionamento.

  • Nell'esempio sopra, la funzione denominata index restituisce il parametro "Hello World !!!".

  • L'ultima riga avvia il server web e chiama la classe specificata (qui, demoExample) e restituisce il valore menzionato nell'indice della funzione predefinita.

Il codice di esempio restituisce il seguente output:

CherryPy viene fornito con il proprio server web (HTTP). Questo è il motivo per cui CherryPy è autonomo e consente agli utenti di eseguire un'applicazione CherryPy entro pochi minuti dall'ottenimento della libreria.

Il web server funge da gateway per l'applicazione con l'aiuto del quale vengono tenute traccia di tutte le richieste e risposte.

Per avviare il server web, un utente deve effettuare la seguente chiamata:

cherryPy.server.quickstart()

Il internal engine of CherryPy è responsabile delle seguenti attività:

  • Creazione e gestione di oggetti di richiesta e risposta.
  • Controllo e gestione del processo CherryPy.

CherryPy - Configurazione

Il framework viene fornito con un proprio sistema di configurazione che consente di parametrizzare il server HTTP. Le impostazioni per la configurazione possono essere memorizzate o in un file di testo con sintassi simile al formato INI o come un dizionario Python completo.

Per configurare l'istanza del server CherryPy, lo sviluppatore deve utilizzare la sezione globale delle impostazioni.

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"

Conformità HTTP

CherryPy si è evoluta lentamente ma include la compilazione di specifiche HTTP con il supporto di HTTP / 1.0, successivamente trasferite con il supporto di HTTP / 1.1.

Si dice che CherryPy sia condizionatamente conforme a HTTP / 1.1 poiché implementa tutti i livelli obbligatori e richiesti ma non tutti i livelli obbligatori della specifica. Pertanto, CherryPy supporta le seguenti funzionalità di HTTP / 1.1:

  • Se un client dichiara di supportare HTTP / 1.1, deve inviare un campo di intestazione in qualsiasi richiesta effettuata con la versione del protocollo specificata. Se non viene fatto, CherryPy interromperà immediatamente l'elaborazione della richiesta.

  • CherryPy genera un campo di intestazione Data che viene utilizzato in tutte le configurazioni.

  • CherryPy può gestire il codice di stato della risposta (100) con il supporto dei client.

  • Il server HTTP integrato di CherryPy supporta le connessioni persistenti che sono predefinite in HTTP / 1.1, tramite l'uso dell'intestazione Connection: Keep-Alive.

  • CherryPy gestisce correttamente le richieste e le risposte suddivise in blocchi.

  • CherryPy supporta le richieste in due modi distinti: le intestazioni If-Modified-Since e If-Unmodified-Since e invia di conseguenza le risposte secondo le richieste.

  • CherryPy consente qualsiasi metodo HTTP.

  • CherryPy gestisce le combinazioni di versioni HTTP tra il client e l'impostazione impostata per il server.

Server applicazioni multithread

CherryPy è progettato sulla base del concetto di multithreading. Ogni volta che uno sviluppatore ottiene o imposta un valore nello spazio dei nomi CherryPy, viene eseguito nell'ambiente multi-thread.

Sia cherrypy.request che cherrypy.response sono contenitori di dati di thread, il che implica che la tua applicazione li chiama in modo indipendente sapendo quale richiesta viene trasmessa tramite proxy in fase di esecuzione.

I server delle applicazioni che utilizzano il modello threaded non sono molto apprezzati perché l'uso di thread è visto come un aumento della probabilità di problemi a causa dei requisiti di sincronizzazione.

Le altre alternative includono:

Pattern multiprocesso

Ogni richiesta viene gestita dal proprio processo Python. In questo caso, le prestazioni e la stabilità del server possono essere considerate migliori.

Modello asincrono

Qui, l'accettazione di nuove connessioni e la restituzione dei dati al client viene eseguita in modo asincrono dal processo di richiesta. Questa tecnica è nota per la sua efficienza.

Invio di URL

La comunità di CherryPy vuole essere più flessibile e che altre soluzioni per gli spedizionieri sarebbero apprezzate. CherryPy 3 fornisce altri dispatcher integrati e offre un modo semplice per scrivere e utilizzare i propri dispatcher.

  • Applicazioni utilizzate per sviluppare metodi HTTP. (GET, POST, PUT, ecc.)
  • Quello che definisce le rotte nell'URL - Routes Dispatcher

HTTP Method Dispatcher

In alcune applicazioni, gli URI sono indipendenti dall'azione, che deve essere eseguita dal server sulla risorsa.

Per esempio,http://xyz.com/album/delete/10

L'URI contiene l'operazione che il client desidera eseguire.

Per impostazione predefinita, il dispatcher di CherryPy viene mappato nel modo seguente:

album.delete(12)

Il suddetto dispatcher è menzionato correttamente, ma può essere reso indipendente nel modo seguente:

http://xyz.com/album/10

L'utente potrebbe chiedersi come il server invia la pagina esatta. Queste informazioni vengono trasportate dalla richiesta HTTP stessa. Quando c'è una richiesta dal client al server, CherryPy sembra il miglior gestore adatto, il gestore è la rappresentazione della risorsa targetizzata dall'URI.

DELETE /album/12 HTTP/1.1

Dispatcher delle rotte

Di seguito è riportato un elenco dei parametri per il metodo richiesto per l'invio:

  • Il parametro name è il nome univoco della route da connettere.

  • La rotta è il modello per abbinare gli URI.

  • Il controller è l'istanza che contiene i gestori di pagine.

  • L'utilizzo del dispatcher di Routes collega un modello che corrisponde agli URI e associa un gestore di pagine specifico.

Esempio

Facciamo un esempio per capire come funziona:

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

Seguire i passaggi indicati di seguito per ottenere l'output del codice sopra -

Step 1 - Salva il file sopra menzionato come tutRoutes.py.

Step 2 - Visita il seguente URL -

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

Step 3 - Riceverai il seguente output -

All'interno di CherryPy, gli strumenti integrati offrono un'unica interfaccia per chiamare la libreria CherryPy. Gli strumenti definiti in CherryPy possono essere implementati nei seguenti modi:

  • Dalle impostazioni di configurazione
  • Come decoratore Python o tramite l'attributo speciale _cp_config di un gestore di pagine
  • Come un Python callable che può essere applicato da qualsiasi funzione

Strumento di autenticazione di base

Lo scopo di questo strumento è fornire l'autenticazione di base all'applicazione progettata nell'applicazione.

argomenti

Questo strumento utilizza i seguenti argomenti:

Nome Predefinito Descrizione
regno N / A Stringa che definisce il valore dell'area di autenticazione.
utenti N / A Dizionario della forma - nome utente: password o una funzione richiamabile Python che restituisce tale dizionario.
crittografare Nessuna Python callable utilizzato per crittografare la password restituita dal client e confrontarla con la password crittografata fornita nel dizionario degli utenti.

Esempio

Facciamo un esempio per capire come funziona:

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)

Il get_usersrestituisce un dizionario hardcoded ma recupera anche i valori da un database o altrove. L'amministratore della classe include questa funzione che utilizza uno strumento di autenticazione integrato in CherryPy. L'autenticazione crittografa la password e l'ID utente.

Lo strumento di autenticazione di base non è veramente sicuro, poiché la password può essere codificata e decodificata da un intruso.

Strumento di memorizzazione nella cache

Lo scopo di questo strumento è fornire la memorizzazione nella cache del contenuto generato da CherryPy.

argomenti

Questo strumento utilizza i seguenti argomenti:

Nome Predefinito Descrizione
invalid_methods ("POST", "PUT", "DELETE") Tuple di stringhe di metodi HTTP da non memorizzare nella cache. Questi metodi invalideranno (cancelleranno) anche qualsiasi copia cache della risorsa.
cache_Class MemoryCache Oggetto classe da utilizzare per la memorizzazione nella cache

Strumento di decodifica

Lo scopo di questo strumento è decodificare i parametri della richiesta in entrata.

argomenti

Questo strumento utilizza i seguenti argomenti:

Nome Predefinito Descrizione
codifica Nessuna Cerca l'intestazione del tipo di contenuto
Default_encoding "UTF-8" Codifica predefinita da utilizzare quando non viene fornita o trovata nessuna.

Esempio

Facciamo un esempio per capire come funziona:

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(), '/')

Il codice sopra prende una stringa dall'utente e reindirizzerà l'utente alla pagina "hello.html" dove verrà visualizzato come "Hello" con il nome dato.

L'output del codice sopra è il seguente:

hello.html

Le applicazioni full stack forniscono una funzione per creare una nuova applicazione tramite un comando o l'esecuzione del file.

Considera le applicazioni Python come il framework web2py; l'intero progetto / applicazione è creato in termini di framework MVC. Allo stesso modo, CherryPy consente all'utente di impostare e configurare il layout del codice secondo le proprie esigenze.

In questo capitolo impareremo in dettaglio come creare l'applicazione CherryPy ed eseguirla.

File System

Il file system dell'applicazione è mostrato nella seguente schermata:

Ecco una breve descrizione dei vari file che abbiamo nel file system:

  • config.py- Ogni applicazione necessita di un file di configurazione e di un modo per caricarlo. Questa funzionalità può essere definita in config.py.

  • controllers.py- MVC è un modello di progettazione popolare seguito dagli utenti. Il controllers.py è dove vengono implementati tutti gli oggetti che verranno montati su cherrypy.tree .

  • models.py - Questo file interagisce direttamente con il database per alcuni servizi o per la memorizzazione di dati persistenti.

  • server.py - Questo file interagisce con il server Web pronto per la produzione che funziona correttamente con il proxy di bilanciamento del carico.

  • Static - Include tutti i file CSS e immagine.

  • Views - Include tutti i file modello per una determinata applicazione.

Esempio

Impariamo in dettaglio i passaggi per creare un'applicazione CherryPy.

Step 1 - Creare un'applicazione che dovrebbe contenere l'applicazione.

Step 2- All'interno della directory, crea un pacchetto python corrispondente al progetto. Crea la directory gedit e includi il file _init_.py all'interno della stessa.

Step 3 - All'interno del pacchetto, includi il file controllers.py con il seguente contenuto -

#!/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- Considera un'applicazione in cui l'utente inserisce il valore tramite un modulo. Includiamo due moduli: index.html e submit.html nell'applicazione.

Step 5 - Nel codice sopra per i controller, abbiamo index(), che è una funzione predefinita e viene caricata per prima se viene chiamato un determinato controller.

Step 6 - L'implementazione del index() il metodo può essere modificato nel modo seguente:

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

Step 7- Questo caricherà index.html all'avvio dell'applicazione data e lo indirizzerà al flusso di output specificato. Il file index.html è il seguente:

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 - È importante aggiungere un metodo alla classe Root in controller.py se vuoi creare un modulo che accetti valori come nomi e titoli.

@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 - Il codice da includere in submit.html è il seguente -

<!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 - Riceverai il seguente output -

Qui, il nome del metodo è definito come "POST". È sempre importante effettuare una verifica incrociata del metodo specificato nel file. Se il metodo include il metodo "POST", i valori devono essere ricontrollati nel database nei campi appropriati.

Se il metodo include il metodo "GET", i valori da salvare saranno visibili nell'URL.

Un servizio Web è un insieme di componenti basati sul Web che aiuta nello scambio di dati tra l'applicazione o i sistemi che include anche protocolli e standard aperti. Può essere pubblicato, utilizzato e trovato sul web.

I servizi Web sono di vari tipi come RWS (RESTfUL Web Service), WSDL, SOAP e molti altri.

REST - Trasferimento di stato rappresentativo

Un tipo di protocollo di accesso remoto che trasferisce lo stato dal client al server che può essere utilizzato per manipolare lo stato invece di chiamare procedure remote.

  • Non definisce alcuna codifica o struttura specifica e modi per restituire messaggi di errore utili.

  • Utilizza i "verbi" HTTP per eseguire operazioni di trasferimento di stato.

  • Le risorse vengono identificate in modo univoco tramite URL.

  • Non è un'API ma piuttosto un livello di trasporto API.

REST mantiene la nomenclatura delle risorse su una rete e fornisce un meccanismo unificato per eseguire operazioni su queste risorse. Ogni risorsa è identificata da almeno un identificatore. Se l'infrastruttura REST viene implementata con la base HTTP, questi identificatori vengono definiti comeUniform Resource Identifiers (URIs).

I seguenti sono i due sottoinsiemi comuni del set di URI:

Sottoinsieme Modulo completo Esempio
URL Localizzatore di risorse uniformi http://www.gmail.com/
URNA Nome risorsa uniforme urna: isbn: 0-201-71088-9 urna: uuid: 13e8cf26-2a25-11db-8693-000ae4ea7d46

Prima di comprendere l'implementazione dell'architettura CherryPy, concentriamoci sull'architettura di CherryPy.

CherryPy include i seguenti tre componenti:

  • cherrypy.engine - Controlla l'avvio / smontaggio del processo e la gestione degli eventi.

  • cherrypy.server - Configura e controlla il server WSGI o HTTP.

  • cherrypy.tools - Una cassetta degli attrezzi di utilità ortogonali all'elaborazione di una richiesta HTTP.

Interfaccia REST tramite CherryPy

Il servizio web RESTful implementa ogni sezione dell'architettura CherryPy con l'aiuto di quanto segue:

  • Authentication
  • Authorization
  • Structure
  • Encapsulation
  • Gestione degli errori

Autenticazione

L'autenticazione aiuta a convalidare gli utenti con cui stiamo interagendo. CherryPy include strumenti per gestire ogni metodo di autenticazione.

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)

La funzione di cui sopra authenticate () aiuterà a convalidare l'esistenza dei client o degli utenti. Gli strumenti integrati aiutano a completare il processo in modo sistematico.

Autorizzazione

L'autorizzazione aiuta a mantenere l'integrità del processo tramite URI. Il processo aiuta anche a trasformare gli oggetti in base ai lead dei token dell'utente.

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

Gli strumenti di autorizzazione incorporati aiutano a gestire le routine in modo sistematico, come menzionato nell'esempio precedente.

Struttura

Mantenere una struttura di API aiuta a ridurre il carico di lavoro della mappatura dell'URI dell'applicazione. È sempre necessario mantenere l'API rilevabile e pulita. La struttura di base dell'API per il framework CherryPy dovrebbe avere quanto segue:

  • Account e utente
  • Autoresponder
  • Contact
  • File
  • Folder
  • Elenco e campo
  • Messaggio e batch

Incapsulamento

L'incapsulamento aiuta nella creazione di API leggere, leggibili e accessibili a vari client. L'elenco degli elementi insieme a Creazione, Recupero, Aggiornamento ed Eliminazione richiede l'incapsulamento dell'API.

Gestione degli errori

Questo processo gestisce gli eventuali errori se l'API non viene eseguita secondo l'istinto particolare. Ad esempio, 400 è per richiesta non valida e 403 è per richiesta non autorizzata.

Esempio

Considera quanto segue come esempio per errori di database, convalida o applicazione.

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

Il codice precedente produrrà il seguente output:

La gestione dell'API (Application Programming Interface) è facile tramite CherryPy grazie agli strumenti di accesso integrati.

Metodi HTTP

L'elenco dei metodi HTTP che operano sulle risorse è il seguente:

S.No Metodo e funzionamento HTTP
1.

HEAD

Recupera i metadati della risorsa.

2.

GET

Recupera i metadati e il contenuto della risorsa.

3.

POST

Richiede al server di creare una nuova risorsa utilizzando i dati racchiusi nel corpo della richiesta.

4.

PUT

Richiede al server di sostituire una risorsa esistente con quella racchiusa nel corpo della richiesta.

5.

DELETE

Richiede al server di rimuovere la risorsa identificata da quell'URI.

6.

OPTIONS

Richiede al server di restituire dettagli sulle capacità a livello globale o specifico per una risorsa.

Atom Publishing Protocol (APP)

L'APP è nata dalla comunità Atom come protocollo a livello di applicazione su HTTP per consentire la pubblicazione e la modifica delle risorse web. L'unità di messaggi tra un server APP e un client si basa sul formato del documento XML Atom.

L'Atom Publishing Protocol definisce un insieme di operazioni tra un servizio APP e uno user-agent utilizzando HTTP e i suoi meccanismi e il formato di documento XML Atom come unità di messaggi.

APP definisce innanzitutto un documento di servizio, che fornisce all'agente utente l'URI delle diverse raccolte servite dal servizio APP.

Esempio

Facciamo un esempio per dimostrare come funziona 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 specifica come eseguire le operazioni CRUD di base su un membro di una raccolta o la raccolta stessa utilizzando i metodi HTTP come descritto nella tabella seguente:

Operazione Metodo HTTP Codice di stato Soddisfare
Recuperare OTTENERE 200 Una voce Atom che rappresenta la risorsa
Creare INVIARE 201 L'URI della risorsa appena creata tramite le intestazioni Location e Content-Location
Aggiornare METTERE 200 Una voce Atom che rappresenta la risorsa
Elimina ELIMINA 200 Nessuna

Il livello di presentazione garantisce che la comunicazione che lo attraversa sia indirizzata ai destinatari previsti. CherryPy mantiene il funzionamento del livello di presentazione tramite vari motori di modelli.

Un motore di modelli prende l'input della pagina con l'aiuto della logica aziendale e quindi lo elabora alla pagina finale che si rivolge solo al pubblico previsto.

Kid - Il motore dei modelli

Kid è un semplice motore di template che include il nome del template da elaborare (che è obbligatorio) e l'inserimento dei dati da passare al momento del rendering del template.

Alla creazione del modello per la prima volta, Kid crea un modulo Python che può essere servito come versione cache del modello.

Il kid.Template restituisce un'istanza della classe template che può essere utilizzata per eseguire il rendering del contenuto di output.

La classe template fornisce il seguente set di comandi:

S.No Comando e descrizione
1.

serialize

Restituisce il contenuto di output come una stringa.

2.

generate

Restituisce il contenuto di output come iteratore.

3.

write

Scarica il contenuto di output in un oggetto file.

I parametri utilizzati da questi comandi sono i seguenti:

S.No Comando e descrizione
1.

encoding

Informa su come codificare il contenuto di output

2.

fragment

È un valore booleano che indica al prologo XML o al Doctype

3.

output

Questo tipo di serializzazione viene utilizzato per il rendering del contenuto

Esempio

Facciamo un esempio per capire come kid funziona -

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

Attributi del bambino

I seguenti sono gli attributi di Kid -

Linguaggio per modelli basato su XML

È un linguaggio basato su XML. Un modello Kid deve essere un documento XML ben formato con convenzioni di denominazione appropriate.

Kid implementa attributi all'interno degli elementi XML per aggiornare il motore sottostante sull'azione da seguire per raggiungere l'elemento. Per evitare la sovrapposizione con altri attributi esistenti all'interno del documento XML, Kid ha introdotto il proprio spazio dei nomi.

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

Sostituzione variabile

Kid viene fornito con uno schema di sostituzione delle variabili e un approccio semplice: $ {nome-variabile}.

Le variabili possono essere utilizzate negli attributi degli elementi o come contenuto di testo di un elemento. Kid valuterà la variabile ogni volta che avrà luogo l'esecuzione.

Se l'utente ha bisogno dell'output di una stringa letterale come $ {qualcosa}, può essere evitato usando la sostituzione della variabile raddoppiando il segno del dollaro.

Dichiarazione condizionale

Per alternare diversi casi nel modello, viene utilizzata la seguente sintassi:

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

Qui, tag è il nome dell'elemento, ad esempio DIV o SPAN.

L'espressione è un'espressione Python. Se come booleano restituisce True, l'elemento verrà incluso nel contenuto di output oppure non farà parte del contenuto di output.

Meccanismo di loop

Per il loop di un elemento in Kid, viene utilizzata la seguente sintassi:

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

Qui, tag è il nome dell'elemento. L'espressione è un'espressione Python, ad esempio per il valore in [...].

Esempio

Il codice seguente mostra come funziona il meccanismo di loop:

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

Il output per il codice sopra con il meccanismo di loop è il seguente:

Fino al 2005, il modello seguito in tutte le applicazioni web era quello di gestire una richiesta HTTP per pagina. La navigazione da una pagina all'altra richiedeva il caricamento della pagina completa. Ciò ridurrebbe le prestazioni a un livello maggiore.

Quindi, c'è stato un aumento di rich client applications che utilizzava per incorporare AJAX, XML e JSON con loro.

AJAX

JavaScript e XML asincrono (AJAX) è una tecnica per creare pagine web veloci e dinamiche. AJAX consente di aggiornare le pagine Web in modo asincrono scambiando piccole quantità di dati dietro le quinte con il server. Ciò significa che è possibile aggiornare parti di una pagina web, senza ricaricare l'intera pagina.

Google Maps, Gmail, YouTube e Facebook sono alcuni esempi di applicazioni AJAX.

Ajax si basa sull'idea di inviare richieste HTTP utilizzando JavaScript; più specificamente AJAX si basa sull'oggetto XMLHttpRequest e sulla sua API per eseguire queste operazioni.

JSON

JSON è un modo per trasportare oggetti JavaScript serializzati in modo tale che l'applicazione JavaScript possa valutarli e trasformarli in oggetti JavaScript che possono essere manipolati in seguito.

Ad esempio, quando l'utente richiede al server un oggetto album formattato con il formato JSON, il server restituirà l'output come segue:

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

Ora i dati sono un array associativo JavaScript e il campo della descrizione è accessibile tramite -

data ['description'];

Applicazione di AJAX all'applicazione

Considera l'applicazione che include una cartella denominata "media" con index.html e plug-in Jquery e un file con implementazione AJAX. Consideriamo il nome del file come "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()

La classe "AjaxApp" reindirizza alla pagina web di "index.html", che è inclusa nella cartella dei media.

<!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>

La funzione per AJAX è inclusa nei tag <script>.

Produzione

Il codice precedente produrrà il seguente output:

Una volta che il valore è stato inviato dall'utente, la funzionalità AJAX viene implementata e lo schermo viene reindirizzato al modulo come mostrato di seguito -

In questo capitolo, ci concentreremo su come viene creata un'applicazione nel framework CherryPy.

Ritenere Photoblogapplicazione per l'applicazione demo di CherryPy. Un'applicazione Photoblog è un normale blog ma il testo principale saranno le foto al posto del testo. Il problema principale dell'applicazione Photoblog è che lo sviluppatore può concentrarsi maggiormente sulla progettazione e sull'implementazione.

Struttura di base - Design delle entità

Le entità progettano la struttura di base di un'applicazione. Le seguenti sono le entità per l'applicazione Photoblog:

  • Film
  • Photo
  • Album

Quello che segue è un diagramma delle classi di base per la relazione di entità:

Struttura del design

Come discusso nel capitolo precedente, la struttura di progettazione del progetto sarebbe come mostrato nella seguente schermata:

Considera l'applicazione data, che ha sottodirectory per l'applicazione Photoblog. Le sottodirectory sono Photo, Album e Film che includerebbero controllers.py, models.py e server.py.

Funzionalmente, l'applicazione Photoblog fornirà API per manipolare quelle entità tramite la tradizionale interfaccia CRUD - Crea, Recupera, Aggiorna ed Elimina.

Connessione al database

Un modulo di archiviazione include una serie di operazioni; connessione con il database essendo una delle operazioni.

Trattandosi di un'applicazione completa, la connessione con il database è obbligatoria per API e per mantenere le funzionalità di Crea, Recupera, Aggiorna ed Elimina.

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

L'arena nel codice precedente sarà la nostra interfaccia tra il gestore di archiviazione sottostante e il livello di logica aziendale.

La funzione connect aggiunge uno storage manager all'oggetto arena per un RDBMS PostgreSQL.

Una volta ottenuta la connessione, possiamo creare moduli secondo le esigenze aziendali e completare il funzionamento dell'applicazione.

La cosa più importante prima della creazione di qualsiasi applicazione è entity mapping e progettare la struttura dell'applicazione.

Il test è un processo durante il quale l'applicazione viene condotta da diverse prospettive al fine di:

  • Trova l'elenco dei problemi
  • Trova le differenze tra il risultato atteso e quello effettivo, l'output, gli stati, ecc.
  • Comprendere la fase di implementazione.
  • Trova l'applicazione utile per scopi realistici.

L'obiettivo del test non è quello di mettere in colpa lo sviluppatore, ma di fornire strumenti e migliorare la qualità per stimare lo stato di salute dell'applicazione in un dato momento.

I test devono essere pianificati in anticipo. Ciò richiede la definizione dello scopo del test, la comprensione della portata dei casi di test, la compilazione dell'elenco dei requisiti aziendali e la consapevolezza dei rischi coinvolti nelle diverse fasi del progetto.

Il test è definito come una serie di aspetti da convalidare su un sistema o un'applicazione. Di seguito è riportato un elenco dei filecommon test approaches -

  • Unit testing- Questo di solito viene eseguito dagli stessi sviluppatori. Questo ha lo scopo di verificare se un'unità di codice funziona come previsto o meno.

  • Usability testing- Gli sviluppatori di solito possono dimenticare che stanno scrivendo un'applicazione per gli utenti finali che non hanno conoscenza del sistema. I test di usabilità verificano i pro ei contro del prodotto.

  • Functional/Acceptance testing - Mentre il test di usabilità verifica se un'applicazione o un sistema è utilizzabile, il test funzionale garantisce che ogni funzionalità specificata sia implementata.

  • Load and performance testing- Viene eseguito per capire se il sistema può adattarsi ai test di carico e di prestazione da condurre. Questo può portare a modifiche nell'hardware, ottimizzazione delle query SQL, ecc.

  • Regression testing - Verifica che i successivi rilasci di un prodotto non interrompano nessuna delle funzionalità precedenti.

  • Reliability and resilience testing - I test di affidabilità aiutano a convalidare l'applicazione di sistema con la rottura di uno o più componenti.

Test unitario

Le applicazioni Photoblog utilizzano costantemente unit test per verificare quanto segue:

  • Le nuove funzionalità funzionano correttamente e come previsto.
  • Le funzionalità esistenti non vengono interrotte dal nuovo rilascio di codice.
  • I difetti vengono risolti e rimangono fissi.

Python viene fornito con un modulo unittest standard che offre un approccio diverso allo unit test.

Unittest

unittest è radicato in JUnit, un pacchetto di unit test Java sviluppato da Kent Beck e Erich Gamma. Gli unit test restituiscono semplicemente dati definiti. È possibile definire oggetti fittizi. Questi oggetti consentono il test su un'interfaccia del nostro progetto senza dover fare affidamento sull'applicazione complessiva. Forniscono anche un modo per eseguire test in modalità isolamento con altri test inclusi.

Definiamo una classe fittizia nel modo seguente:

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)

La spiegazione del codice è la seguente:

  • Il modulo unittest dovrebbe essere importato per fornire funzionalità di unit test per la classe data.

  • Una classe dovrebbe essere creata sottoclasse unittest.

  • Ogni metodo nel codice precedente inizia con un test di parole. Tutti questi metodi vengono chiamati dal gestore unittest.

  • I metodi assert / fail vengono chiamati dal test case per gestire le eccezioni.

Considera questo come un esempio per eseguire un test case:

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

Il risultato (output) per l'esecuzione del test case sarà il seguente:

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

Test funzionali

Una volta che le funzionalità dell'applicazione iniziano a prendere forma secondo i requisiti, una serie di test funzionali può convalidare la correttezza dell'applicazione rispetto alle specifiche. Tuttavia, il test dovrebbe essere automatizzato per ottenere prestazioni migliori che richiederebbero l'uso di prodotti di terze parti come Selenium.

CherryPy fornisce classi di supporto come funzioni integrate per facilitare la scrittura di test funzionali.

Test di carico

A seconda dell'applicazione che si sta scrivendo e delle proprie aspettative in termini di volume, potrebbe essere necessario eseguire test di carico e prestazioni per rilevare potenziali colli di bottiglia nell'applicazione che le impediscono di raggiungere un certo livello di prestazioni.

Questa sezione non spiegherà in dettaglio come condurre un test delle prestazioni o del carico poiché è fuori dal pacchetto FunkLoad.

L'esempio di base di FunkLoad è il seguente:

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

Ecco una spiegazione dettagliata del codice sopra -

  • Il test case deve ereditare dalla classe FunkLoadTestCase in modo che FunkLoad possa svolgere il suo compito interno di tenere traccia di ciò che accade durante il test.

  • Il nome della classe è importante poiché FunkLoad cercherà un file in base al nome della classe.

  • I casi di test progettati hanno accesso diretto ai file di configurazione. I metodi Get () e post () vengono semplicemente chiamati sul server per ottenere la risposta.

Questo capitolo si concentrerà maggiormente sull'applicazione basata su CherryPy SSL abilitata tramite il server HTTP CherryPy integrato.

Configurazione

Ci sono diversi livelli di impostazioni di configurazione richieste in un'applicazione web:

  • Web server - Impostazioni collegate al server HTTP

  • Engine - Impostazioni associate all'hosting del motore

  • Application - Applicazione che viene utilizzata dall'utente

Distribuzione

La distribuzione dell'applicazione CherryPy è considerata un metodo abbastanza semplice in cui tutti i pacchetti richiesti sono disponibili dal percorso del sistema Python. Nell'ambiente ospitato sul Web condiviso, il server Web risiederà nel front-end che consente al provider host di eseguire le azioni di filtro. Il server front-end può essere Apache olighttpd.

Questa sezione presenterà alcune soluzioni per eseguire un'applicazione CherryPy dietro i server web Apache e 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)può essere supportato nelle applicazioni basate su CherryPy. Per abilitare il supporto SSL, devono essere soddisfatti i seguenti requisiti:

  • Avere il pacchetto PyOpenSSL installato nell'ambiente dell'utente
  • Avere un certificato SSL e una chiave privata sul server

Creazione di un certificato e una chiave privata

Affrontiamo i requisiti del certificato e della chiave privata -

  • Per prima cosa l'utente ha bisogno di una chiave privata -
openssl genrsa -out server.key 2048
  • Questa chiave non è protetta da password e quindi ha una protezione debole.
  • Verrà emesso il seguente comando:
openssl genrsa -des3 -out server.key 2048
  • Il programma richiederà una passphrase. Se la tua versione di OpenSSL ti consente di fornire una stringa vuota, fallo. Altrimenti, inserisci una passphrase predefinita e quindi rimuovila dalla chiave generata come segue:

openssl rsa -in server.key -out server.key
  • La creazione del certificato è la seguente:
openssl req -new -key server.key -out server.csr
  • Questo processo richiederà di inserire alcuni dettagli. Per fare ciò, deve essere emesso il seguente comando:

openssl x509 -req -days 60 -in server.csr -signkey
server.key -out server.crt
  • Il certificato appena firmato sarà valido per 60 giorni.

Il codice seguente mostra la sua implementazione:

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

Il passo successivo è avviare il server; se hai successo, vedrai il seguente messaggio sullo schermo:

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