CherryPy - Guia rápido

CherryPy é uma estrutura web de Python que fornece uma interface amigável para o protocolo HTTP para desenvolvedores Python. Também é chamada de biblioteca de aplicativos da web.

CherryPy usa os pontos fortes do Python como uma linguagem dinâmica para modelar e vincular o protocolo HTTP a uma API. É uma das estruturas da web mais antigas para Python, que fornece interface limpa e plataforma confiável.

História do CherryPy

Remi Delon lançou a primeira versão do CherryPy no final de junho de 2002. Este foi o ponto de partida de uma biblioteca web Python de sucesso. Remi é um hacker francês que confiou no Python por ser uma das maiores alternativas para o desenvolvimento de aplicativos web.

O projeto desenvolvido por Remi atraiu vários desenvolvedores interessados ​​na abordagem. A abordagem incluiu os seguintes recursos -

  • CherryPy estava próximo do padrão model-view-controller.

  • Uma classe CherryPy deve ser processada e compilada pelo mecanismo CherryPy para produzir um módulo Python independente que incorpora o aplicativo completo e também seu próprio servidor web embutido.

  • CherryPy pode mapear um URL e sua string de consulta em uma chamada de método Python, por exemplo -

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

Durante os dois anos de desenvolvimento no projeto CherryPy, ele foi apoiado pela comunidade e Remi lançou várias versões melhoradas.

Em junho de 2004, uma discussão começou sobre o futuro do projeto e se ele deveria continuar com a mesma arquitetura. O brainstorming e a discussão por vários participantes do projeto levaram ao conceito de mecanismo de publicação de objetos e filtros, que logo se tornou uma parte central do CherryPy2.Mais tarde, em outubro de 2004, a primeira versão do CherryPy 2 alpha foi lançada como uma prova de conceito de essas idéias centrais. CherryPy 2.0 foi um verdadeiro sucesso; no entanto, foi reconhecido que seu design ainda poderia ser melhorado e precisava de refatoração.

Depois de discussões baseadas em feedbacks, a API do CherryPy foi modificada para melhorar sua elegância, levando ao lançamento do CherryPy 2.1.0 em outubro de 2005. Após várias mudanças, a equipe lançou o CherryPy 2.2.0 em abril de 2006.

Forças do CherryPy

Os seguintes recursos do CherryPy são considerados seus pontos fortes -

Simplicidade

Desenvolver um projeto em CherryPy é uma tarefa simples com poucas linhas de código desenvolvidas de acordo com as convenções e indentações do Python.

CherryPy também é muito modular. Os componentes primários são bem gerenciados com o conceito lógico correto e as classes pai são expansíveis para classes filho.

Poder

CherryPy aproveita todo o poder do Python. Ele também fornece ferramentas e plug-ins, que são pontos de extensão poderosos necessários para desenvolver aplicativos de classe mundial.

Código aberto

CherryPy é um Python Web Framework de código aberto (licenciado sob a licença BSD de código aberto), o que significa que este framework pode ser usado comercialmente a custo ZERO.

Ajuda da comunidade

Possui uma comunidade dedicada que fornece suporte completo com vários tipos de perguntas e respostas. A comunidade tenta dar assistência completa aos desenvolvedores, desde o nível iniciante ao avançado.

Desdobramento, desenvolvimento

Existem maneiras econômicas de implantar o aplicativo. CherryPy inclui seu próprio servidor HTTP pronto para produção para hospedar seu aplicativo. CherryPy também pode ser implantado em qualquer gateway compatível com WSGI.

CherryPy vem em pacotes como a maioria dos projetos de código aberto, que podem ser baixados e instalados de várias maneiras, mencionadas a seguir -

  • Usando um Tarball
  • Usando easy_install
  • Usando Subversion

Requisitos

Os requisitos básicos para instalação do framework CherryPy incluem -

  • Python com versão 2.4 ou superior
  • CherryPy 3.0

Instalar um módulo Python é considerado um processo fácil. A instalação inclui o uso dos seguintes comandos.

python setup.py build
python setup.py install

Os pacotes do Python são armazenados nos seguintes diretórios padrão -

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

Instalação usando Tarball

Um Tarball é um arquivo compactado de arquivos ou um diretório. A estrutura CherryPy fornece um Tarball para cada uma de suas versões (alfa, beta e estável).

Ele contém o código-fonte completo da biblioteca. O nome vem do utilitário usado no UNIX e outros sistemas operacionais.

Aqui estão os passos a serem seguidos para a instalação do CherryPy usando tar ball -

Step 1 - Baixe a versão de acordo com os requisitos do usuário em http://download.cherrypy.org/

Step 2- Procure o diretório onde o Tarball foi baixado e descompacte-o. Para o sistema operacional Linux, digite o seguinte comando -

tar zxvf cherrypy-x.y.z.tgz

Para o Microsoft Windows, o usuário pode usar um utilitário como o 7-Zip ou Winzip para descompactar o arquivo por meio de uma interface gráfica.

Step 3 - Mova para o diretório recém-criado e use o seguinte comando para construir o CherryPy -

python setup.py build

Para a instalação global, o seguinte comando deve ser usado -

python setup.py install

Instalação usando easy_install

O Python Enterprise Application Kit (PEAK) fornece um módulo Python denominado Easy Install. Isso facilita a implantação dos pacotes Python. Este módulo simplifica o procedimento de download, construção e implantação de aplicativos e produtos Python.

O Easy Install precisa ser instalado no sistema antes de instalar o CherryPy.

Step 1 - Baixe o módulo ez_setup.py em http://peak.telecommunity.com e execute-o usando os direitos administrativos no computador: python ez_setup.py.

Step 2 - O seguinte comando é usado para instalar o Easy Install.

easy_install product_name

Step 3- easy_install irá pesquisar o índice de pacotes Python (PyPI) para encontrar o produto fornecido. PyPI é um repositório centralizado de informações para todos os produtos Python.

Use o seguinte comando para implantar a última versão disponível do CherryPy -

easy_install cherrypy

Step 4 - easy_install irá então baixar o CherryPy, construir e instalá-lo globalmente em seu ambiente Python.

Instalação usando Subversion

A instalação do CherryPy usando Subversion é recomendada nas seguintes situações -

  • Existe um recurso ou um bug foi corrigido e está disponível apenas no código em desenvolvimento.

  • Quando o desenvolvedor trabalha no próprio CherryPy.

  • Quando o usuário precisa de um branch do branch principal no repositório de controle de versão.

  • Para correção de bugs da versão anterior.

O princípio básico do subversioning é registrar um repositório e manter um registro de cada uma das versões, o que inclui uma série de mudanças nelas.

Siga estes passos para entender a instalação do CherryPy usando Subversion−

Step 1 - Para usar a versão mais recente do projeto, é necessário verificar a pasta trunk encontrada no repositório Subversion.

Step 2 - Digite o seguinte comando em um shell−

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

Step 3 - Agora, crie um diretório CherryPy e baixe o código-fonte completo nele.

Testando a instalação

É necessário verificar se o aplicativo foi instalado corretamente no sistema ou não da mesma forma que fazemos para aplicativos como Java.

Você pode escolher qualquer um dos três métodos mencionados no capítulo anterior para instalar e implantar o CherryPy em seu ambiente. CherryPy deve ser capaz de importar do shell Python da seguinte forma -

import cherrypy

cherrypy.__version__
'3.0.0'

Se CherryPy não estiver instalado globalmente no ambiente Python do sistema local, você precisa definir a variável de ambiente PYTHONPATH, caso contrário, ele exibirá um erro da seguinte maneira -

import cherrypy

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

Existem algumas palavras-chave importantes que precisam ser definidas para entender o funcionamento do CherryPy. As palavras-chave e as definições são as seguintes -

S.No Palavra-chave e definição
1

Web Server

É uma interface que lida com o protocolo HTTP. Seu objetivo é transformar as solicitações HTTP para o servidor de aplicativos para que obtenham as respostas.

2

Application

É um software que coleta informações.

3 -

Application server

É o componente que contém um ou mais aplicativos

4 -

Web application server

É a combinação de servidor da web e servidor de aplicativos.

Exemplo

O exemplo a seguir mostra um código de amostra de CherryPy -

import cherrypy

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

Vamos agora entender como o código funciona -

  • O pacote denominado CherryPy é sempre importado na classe especificada para garantir o funcionamento adequado.

  • No exemplo acima, a função chamada index retorna o parâmetro “Hello World !!!”.

  • A última linha inicia o servidor da web e chama a classe especificada (aqui, demoExample) e retorna o valor mencionado no índice de função padrão.

O código de exemplo retorna a seguinte saída -

CherryPy vem com seu próprio servidor web (HTTP). É por isso que o CherryPy é independente e permite que os usuários executem um aplicativo CherryPy poucos minutos depois de obter a biblioteca.

o web server atua como o gateway para o aplicativo, com a ajuda do qual todas as solicitações e respostas são mantidas sob controle.

Para iniciar o servidor web, um usuário deve fazer a seguinte chamada -

cherryPy.server.quickstart()

o internal engine of CherryPy é responsável pelas seguintes atividades -

  • Criação e gerenciamento de objetos de solicitação e resposta.
  • Controlar e gerenciar o processo CherryPy.

CherryPy - Configuração

O framework vem com seu próprio sistema de configuração permitindo parametrizar o servidor HTTP. As configurações para a configuração podem ser armazenadas em um arquivo de texto com sintaxe próxima ao formato INI ou como um dicionário Python completo.

Para configurar a instância do servidor CherryPy, o desenvolvedor precisa usar a seção global das configurações.

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"

Conformidade HTTP

CherryPy tem evoluído lentamente, mas inclui a compilação de especificações HTTP com o suporte de HTTP / 1.0, transferindo posteriormente com o suporte de HTTP / 1.1.

CherryPy é considerado condicionalmente compatível com HTTP / 1.1, uma vez que implementa todos os níveis obrigatórios e obrigatórios, mas não todos os níveis obrigatórios da especificação. Portanto, CherryPy suporta os seguintes recursos de HTTP / 1.1 -

  • Se um cliente afirma suportar HTTP / 1.1, ele deve enviar um campo de cabeçalho em qualquer solicitação feita com a versão de protocolo especificada. Se não for feito, CherryPy interromperá imediatamente o processamento da solicitação.

  • CherryPy gera um campo de cabeçalho de data que é usado em todas as configurações.

  • CherryPy pode lidar com o código de status de resposta (100) com o suporte de clientes.

  • O servidor HTTP embutido do CherryPy suporta conexões persistentes que são o padrão em HTTP / 1.1, através do uso do cabeçalho Connection: Keep-Alive.

  • CherryPy lida com solicitações e respostas em partes corretamente.

  • CherryPy oferece suporte a solicitações de duas maneiras distintas - cabeçalhos If-Modified-Since e If-Unmodified-Since e envia respostas de acordo com as solicitações em conformidade.

  • CherryPy permite qualquer método HTTP.

  • CherryPy lida com as combinações de versões HTTP entre o cliente e a configuração definida para o servidor.

Servidor de aplicativos multithread

CherryPy é projetado com base no conceito de multithreading. Cada vez que um desenvolvedor obtém ou define um valor no namespace CherryPy, isso é feito em um ambiente multithread.

Cherrypy.request e cherrypy.response são contêineres de dados de thread, o que implica que seu aplicativo os chama de forma independente, sabendo qual solicitação é enviada por proxy por meio deles no tempo de execução.

Os servidores de aplicativos que usam o padrão encadeado não são altamente considerados porque o uso de encadeamentos é visto como um aumento da probabilidade de problemas devido aos requisitos de sincronização.

As outras alternativas incluem -

Padrão Multi-processo

Cada solicitação é tratada por seu próprio processo Python. Aqui, o desempenho e a estabilidade do servidor podem ser considerados melhores.

Padrão Assíncrono

Aqui, aceitar novas conexões e enviar os dados de volta ao cliente é feito de forma assíncrona a partir do processo de solicitação. Esta técnica é conhecida por sua eficiência.

Envio de URL

A comunidade CherryPy quer ser mais flexível e que outras soluções para despachantes sejam apreciadas. CherryPy 3 fornece outros despachantes integrados e oferece uma maneira simples de escrever e usar seus próprios despachantes.

  • Aplicativos usados ​​para desenvolver métodos HTTP. (GET, POST, PUT, etc.)
  • Aquele que define as rotas no URL - Routes Dispatcher

Dispatcher de método HTTP

Em alguns aplicativos, os URIs são independentes da ação, que deve ser executada pelo servidor no recurso.

Por exemplo,http://xyz.com/album/delete/10

O URI contém a operação que o cliente deseja realizar.

Por padrão, o despachante CherryPy mapearia da seguinte maneira -

album.delete(12)

O despachante mencionado acima é mencionado corretamente, mas pode ser independente da seguinte maneira -

http://xyz.com/album/10

O usuário pode se perguntar como o servidor despacha a página exata. Essas informações são transportadas pela própria solicitação HTTP. Quando há solicitação do cliente ao servidor, CherryPy parece o manipulador mais adequado, o manipulador é a representação do recurso visado pelo URI.

DELETE /album/12 HTTP/1.1

Expedidor de rotas

Aqui está uma lista dos parâmetros para o método necessário no despacho -

  • O parâmetro name é o nome exclusivo da rota a ser conectada.

  • A rota é o padrão para corresponder aos URIs.

  • O controlador é a instância que contém os manipuladores de página.

  • O uso do distribuidor Routes conecta um padrão que corresponde a URIs e associa um manipulador de página específico.

Exemplo

Vamos dar um exemplo para entender como funciona -

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

Siga as etapas abaixo para obter a saída do código acima -

Step 1 - Salve o arquivo mencionado acima como tutRoutes.py.

Step 2 - Visite o seguinte URL -

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

Step 3 - Você receberá a seguinte saída -

Dentro do CherryPy, as ferramentas integradas oferecem uma única interface para chamar a biblioteca CherryPy. As ferramentas definidas no CherryPy podem ser implementadas das seguintes maneiras -

  • Das definições de configuração
  • Como um decorador Python ou por meio do atributo especial _cp_config de um manipulador de página
  • Como um Python chamável que pode ser aplicado a partir de qualquer função

Ferramenta de autenticação básica

O objetivo desta ferramenta é fornecer autenticação básica para o aplicativo desenvolvido no aplicativo.

Argumentos

Esta ferramenta usa os seguintes argumentos -

Nome Padrão Descrição
reino N / D String que define o valor do reino.
Comercial N / D Dicionário da forma - nome de usuário: senha ou uma função que pode ser chamada de Python retornando tal dicionário.
criptografar Nenhum Python chamável usado para criptografar a senha retornada pelo cliente e compará-la com a senha criptografada fornecida no dicionário do usuário.

Exemplo

Vamos dar um exemplo para entender como funciona -

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)

o get_usersfunção retorna um dicionário embutido em código, mas também busca os valores de um banco de dados ou de qualquer outro lugar. O administrador da classe inclui esta função que faz uso de uma ferramenta de autenticação embutida do CherryPy. A autenticação criptografa a senha e o ID do usuário.

A ferramenta de autenticação básica não é realmente segura, pois a senha pode ser codificada e decodificada por um invasor.

Ferramenta de Cache

O objetivo desta ferramenta é fornecer cache de memória do conteúdo gerado pelo CherryPy.

Argumentos

Esta ferramenta usa os seguintes argumentos -

Nome Padrão Descrição
invalid_methods ("POSTAR", "COLOCAR", "EXCLUIR") Tuplas de strings de métodos HTTP não devem ser armazenadas em cache. Esses métodos também invalidarão (excluirão) qualquer cópia em cache do recurso.
cache_Class MemoryCache Objeto de classe a ser usado para cache

Ferramenta de decodificação

O objetivo desta ferramenta é decodificar os parâmetros de solicitação de entrada.

Argumentos

Esta ferramenta usa os seguintes argumentos -

Nome Padrão Descrição
codificação Nenhum Ele procura o cabeçalho do tipo de conteúdo
Default_encoding "UTF-8" Codificação padrão a ser usada quando nenhuma for fornecida ou encontrada.

Exemplo

Vamos dar um exemplo para entender como funciona -

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

O código acima pega uma string do usuário e redireciona o usuário para a página "hello.html", onde será exibido como “Hello” com o nome fornecido.

A saída do código acima é a seguinte -

hello.html

Os aplicativos full stack fornecem um recurso para criar um novo aplicativo por meio de algum comando ou execução do arquivo.

Considere os aplicativos Python como o framework web2py; todo o projeto / aplicativo é criado em termos de estrutura MVC. Da mesma forma, CherryPy permite ao usuário definir e configurar o layout do código de acordo com seus requisitos.

Neste capítulo, aprenderemos em detalhes como criar um aplicativo CherryPy e executá-lo.

Sistema de arquivo

O sistema de arquivos do aplicativo é mostrado na imagem a seguir -

Aqui está uma breve descrição dos vários arquivos que temos no sistema de arquivos -

  • config.py- Todo aplicativo precisa de um arquivo de configuração e uma forma de carregá-lo. Essa funcionalidade pode ser definida em config.py.

  • controllers.py- MVC é um padrão de design popular seguido pelos usuários. O controllers.py é onde são implementados todos os objetos que serão montados no cherrypy.tree .

  • models.py - Este arquivo interage com o banco de dados diretamente para alguns serviços ou para armazenar dados persistentes.

  • server.py - Este arquivo interage com o servidor da web pronto para produção que funciona corretamente com o proxy de balanceamento de carga.

  • Static - Inclui todos os arquivos CSS e de imagem.

  • Views - Inclui todos os arquivos de modelo para um determinado aplicativo.

Exemplo

Vamos aprender em detalhes as etapas para criar um aplicativo CherryPy.

Step 1 - Crie um aplicativo que deve conter o aplicativo.

Step 2- Dentro do diretório, crie um pacote python correspondente ao projeto. Crie o diretório gedit e inclua o arquivo _init_.py dentro do mesmo.

Step 3 - Dentro do pacote, inclua o arquivo controllers.py com o seguinte conteúdo -

#!/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- Considere um aplicativo em que o usuário insere o valor por meio de um formulário. Vamos incluir dois formulários - index.html e submit.html no aplicativo.

Step 5 - No código acima para controladores, temos index(), que é uma função padrão e carrega primeiro se um controlador específico for chamado.

Step 6 - A implementação do index() método pode ser alterado da seguinte maneira -

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

Step 7- Isso carregará index.html ao iniciar o aplicativo fornecido e direcioná-lo para o fluxo de saída fornecido. O arquivo index.html é o seguinte -

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 adicionar um método à classe Root em controller.py se você deseja criar um formulário que aceite valores como nomes e títulos.

@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 - O código a ser incluído em submit.html é o seguinte -

<!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 - Você receberá a seguinte saída -

Aqui, o nome do método é definido como “POST”. É sempre importante verificar o método especificado no arquivo. Se o método incluir o método “POST”, os valores devem ser verificados novamente no banco de dados nos campos apropriados.

Se o método incluir o método “GET”, os valores a serem salvos ficarão visíveis na URL.

Um serviço da web é um conjunto de componentes baseados na web que auxiliam na troca de dados entre o aplicativo ou sistemas que também inclui protocolos e padrões abertos. Ele pode ser publicado, usado e encontrado na web.

Os serviços da Web são de vários tipos, como RWS (RESTfUL Web Service), WSDL, SOAP e muitos mais.

REST - Transferência de Estado Representacional

Um tipo de protocolo de acesso remoto, que transfere o estado do cliente para o servidor, que pode ser usado para manipular o estado em vez de chamar procedimentos remotos.

  • Não define nenhuma codificação ou estrutura específica e formas de retornar mensagens de erro úteis.

  • Usa "verbos" HTTP para realizar operações de transferência de estado.

  • Os recursos são identificados exclusivamente por URL.

  • Não é uma API, mas sim uma camada de transporte de API.

REST mantém a nomenclatura de recursos em uma rede e fornece um mecanismo unificado para executar operações nesses recursos. Cada recurso é identificado por pelo menos um identificador. Se a infraestrutura REST for implementada com a base de HTTP, esses identificadores são denominados comoUniform Resource Identifiers (URIs).

A seguir estão os dois subconjuntos comuns do conjunto URI -

Subconjunto Formulário completo Exemplo
URL localizador padrão de recursos http://www.gmail.com/
URNA Nome de recurso uniforme urn: isbn: 0-201-71088-9 urn: uuid: 13e8cf26-2a25-11db-8693-000ae4ea7d46

Antes de entender a implementação da arquitetura CherryPy, vamos nos concentrar na arquitetura do CherryPy.

CherryPy inclui os seguintes três componentes -

  • cherrypy.engine - Controla a inicialização / desmontagem de processos e o tratamento de eventos.

  • cherrypy.server - Configura e controla o servidor WSGI ou HTTP.

  • cherrypy.tools - Uma caixa de ferramentas de utilitários ortogonais ao processamento de uma solicitação HTTP.

Interface REST através do CherryPy

O serviço da web RESTful implementa cada seção da arquitetura CherryPy com a ajuda do seguinte -

  • Authentication
  • Authorization
  • Structure
  • Encapsulation
  • Manipulação de erros

Autenticação

A autenticação ajuda a validar os usuários com os quais estamos interagindo. CherryPy inclui ferramentas para lidar com cada método de autenticação.

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)

A função anterior authenticate () ajudará a validar a existência dos clientes ou usuários. As ferramentas integradas ajudam a completar o processo de forma sistemática.

Autorização

A autorização ajuda a manter a sanidade do processo por meio de URI. O processo também ajuda na transformação de objetos por ligações de token do usuário.

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

As ferramentas integradas de autorização auxiliam no manuseio das rotinas de forma sistemática, conforme mencionado no exemplo anterior.

Estrutura

Manter uma estrutura de API ajuda a reduzir a carga de trabalho de mapeamento do URI do aplicativo. É sempre necessário manter a API detectável e limpa. A estrutura básica da API para o framework CherryPy deve ter o seguinte -

  • Contas e usuário
  • Autoresponder
  • Contact
  • File
  • Folder
  • Lista e campo
  • Mensagem e lote

Encapsulamento

O encapsulamento ajuda a criar uma API leve, legível por humanos e acessível a vários clientes. A lista de itens junto com Criação, Recuperação, Atualização e Exclusão requer encapsulamento de API.

Manipulação de erros

Este processo gerencia erros, se houver, se a API falhar ao executar no instinto específico. Por exemplo, 400 é para solicitação incorreta e 403 é para solicitação não autorizada.

Exemplo

Considere o seguinte como um exemplo para erros de banco de dados, validação ou aplicativo.

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

O código acima produzirá a seguinte saída -

O gerenciamento da API (Application Programming Interface) é fácil por meio do CherryPy por causa das ferramentas de acesso integradas.

Métodos HTTP

A lista de métodos HTTP que operam nos recursos é a seguinte -

S.No Método e operação HTTP
1

HEAD

Recupera os metadados do recurso.

2

GET

Recupera os metadados e o conteúdo do recurso.

3 -

POST

Solicita que o servidor crie um novo recurso usando os dados incluídos no corpo da solicitação.

4 -

PUT

Solicita que o servidor substitua um recurso existente por aquele incluído no corpo da solicitação.

5

DELETE

Solicita que o servidor remova o recurso identificado por esse URI.

6

OPTIONS

Solicita que o servidor retorne detalhes sobre os recursos globalmente ou especificamente para um recurso.

Protocolo de Publicação Atom (APP)

O APP surgiu da comunidade Atom como um protocolo de nível de aplicativo acima do HTTP para permitir a publicação e edição de recursos da web. A unidade de mensagens entre um servidor APP e um cliente é baseada no formato de documento Atom XML.

O Atom Publishing Protocol define um conjunto de operações entre um serviço APP e um agente do usuário usando HTTP e seus mecanismos e o formato de documento Atom XML como a unidade de mensagens.

O APP primeiro define um documento de serviço, que fornece ao agente do usuário o URI das diferentes coleções servidas pelo serviço APP.

Exemplo

Vamos dar um exemplo para demonstrar como o APP funciona -

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

O APP especifica como realizar as operações CRUD básicas contra um membro de uma coleção ou a própria coleção usando métodos HTTP, conforme descrito na tabela a seguir -

Operação Método HTTP Código de Status Conteúdo
Recuperar PEGUE 200 Uma entrada Atom que representa o recurso
Crio POSTAR 201 O URI do recurso recém-criado por meio dos cabeçalhos Location e Content-Location
Atualizar COLOCAR 200 Uma entrada Atom que representa o recurso
Excluir EXCLUIR 200 Nenhum

A camada de apresentação garante que a comunicação que passa por ela seja direcionada aos destinatários pretendidos. CherryPy mantém o funcionamento da camada de apresentação por vários mecanismos de template.

Um mecanismo de modelo pega a entrada da página com a ajuda da lógica de negócios e a processa para a página final, que visa apenas o público-alvo.

Kid - o mecanismo de modelo

Kid é um mecanismo de modelo simples que inclui o nome do modelo a ser processado (o que é obrigatório) e a entrada dos dados a serem passados ​​quando o modelo é renderizado.

Na criação do modelo pela primeira vez, Kid cria um módulo Python que pode ser servido como uma versão em cache do modelo.

o kid.Template A função retorna uma instância da classe de modelo que pode ser usada para renderizar o conteúdo de saída.

A classe de modelo fornece o seguinte conjunto de comandos -

S.No Comando e Descrição
1

serialize

Ele retorna o conteúdo de saída como uma string.

2

generate

Ele retorna o conteúdo de saída como um iterador.

3 -

write

Ele despeja o conteúdo de saída em um objeto de arquivo.

Os parâmetros usados ​​por esses comandos são os seguintes -

S.No Comando e Descrição
1

encoding

Informa como codificar o conteúdo de saída

2

fragment

É um valor booleano que informa ao prólogo XML ou Doctype

3 -

output

Este tipo de serialização é usado para renderizar o conteúdo

Exemplo

Vamos dar um exemplo para entender como kid funciona -

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

Atributos infantis

A seguir estão os atributos de Kid -

Linguagem de modelagem baseada em XML

É uma linguagem baseada em XML. Um modelo Kid deve ser um documento XML bem formado com convenções de nomenclatura adequadas.

Kid implementa atributos nos elementos XML para atualizar o mecanismo subjacente sobre a ação a ser seguida para alcançar o elemento. Para evitar a sobreposição com outros atributos existentes no documento XML, Kid introduziu seu próprio namespace.

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

Substituição de Variável

Kid vem com um esquema de substituição de variáveis ​​e uma abordagem simples - $ {nome-da-variável}.

As variáveis ​​podem ser usadas em atributos de elementos ou como conteúdo de texto de um elemento. Kid avaliará a variável toda vez que a execução ocorrer.

Se o usuário precisa da saída de uma string literal como $ {something}, ela pode ser escapada usando a substituição de variável dobrando o cifrão.

Afirmação condicional

Para alternar entre diferentes casos no modelo, a seguinte sintaxe é usada -

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

Aqui, tag é o nome do elemento, por exemplo DIV ou SPAN.

A expressão é uma expressão Python. Se como um Booleano for avaliado como True, o elemento será incluído no conteúdo de saída ou então não fará parte do conteúdo de saída.

Mecanismo de Looping

Para repetir um elemento em Kid, a seguinte sintaxe é usada -

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

Aqui, tag é o nome do elemento. A expressão é uma expressão Python, por exemplo, para valor em [...].

Exemplo

O código a seguir mostra como funciona o mecanismo de 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')

o output para o código acima com o mecanismo de loop é o seguinte -

Até o ano de 2005, o padrão seguido em todos os aplicativos da web era gerenciar uma solicitação HTTP por página. A navegação de uma página para outra exigia o carregamento da página completa. Isso reduziria o desempenho em um nível maior.

Assim, houve um aumento na rich client applications que costumava incorporar AJAX, XML e JSON com eles.

AJAX

JavaScript e XML assíncrono (AJAX) é uma técnica para criar páginas da web rápidas e dinâmicas. O AJAX permite que as páginas da web sejam atualizadas de forma assíncrona, trocando pequenas quantidades de dados nos bastidores com o servidor. Isso significa que é possível atualizar partes de uma página da web, sem recarregar a página inteira.

Google Maps, Gmail, YouTube e Facebook são alguns exemplos de aplicativos AJAX.

O Ajax é baseado na ideia de enviar solicitações HTTP usando JavaScript; mais especificamente, o AJAX depende do objeto XMLHttpRequest e de sua API para realizar essas operações.

JSON

JSON é uma forma de transportar objetos JavaScript serializados de forma que o aplicativo JavaScript possa avaliá-los e transformá-los em objetos JavaScript que podem ser manipulados posteriormente.

Por exemplo, quando o usuário solicita ao servidor um objeto de álbum formatado com o formato JSON, o servidor retorna a saída da seguinte forma -

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

Agora os dados são uma matriz associativa JavaScript e o campo de descrição pode ser acessado via -

data ['description'];

Aplicação de AJAX ao aplicativo

Considere o aplicativo que inclui uma pasta chamada “media” com index.html e plugin Jquery, e um arquivo com implementação AJAX. Vamos considerar o nome do arquivo como “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()

A classe “AjaxApp” redireciona para a página da web “index.html”, que está incluída na pasta de mídia.

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

A função para AJAX está incluída nas tags <script>.

Resultado

O código acima produzirá a seguinte saída -

Assim que o valor é enviado pelo usuário, a funcionalidade AJAX é implementada e a tela é redirecionada para o formulário conforme mostrado abaixo -

Neste capítulo, vamos nos concentrar em como um aplicativo é criado no framework CherryPy.

Considerar Photoblogaplicativo para o aplicativo de demonstração do CherryPy. Um aplicativo Photoblog é um blog normal, mas o texto principal será fotos no lugar do texto. O principal problema do aplicativo Photoblog é que o desenvolvedor pode se concentrar mais no design e na implementação.

Estrutura Básica - Desenho de Entidades

As entidades projetam a estrutura básica de um aplicativo. A seguir estão as entidades para o aplicativo Photoblog -

  • Film
  • Photo
  • Album

A seguir está um diagrama de classe básico para o relacionamento da entidade -

Estrutura de Design

Conforme discutido no capítulo anterior, a estrutura de design do projeto seria conforme mostrado na imagem a seguir -

Considere o aplicativo fornecido, que possui subdiretórios para o aplicativo Photoblog. Os subdiretórios são Photo, Album e Film, que incluem controllers.py, models.py e server.py.

Funcionalmente, o aplicativo Photoblog fornecerá APIs para manipular essas entidades por meio da interface CRUD tradicional - Criar, Recuperar, Atualizar e Excluir.

Conexão com o banco de dados

Um módulo de armazenamento inclui um conjunto de operações; conexão com o banco de dados sendo uma das operações.

Por se tratar de uma aplicação completa, a conexão com banco de dados é obrigatória para API e para manter a funcionalidade de Criar, Recuperar, Atualizar e Excluir.

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

A arena no código acima será nossa interface entre o gerenciador de armazenamento subjacente e a camada de lógica de negócios.

A função de conexão adiciona um gerenciador de armazenamento ao objeto arena para um PostgreSQL RDBMS.

Assim que a conexão for obtida, podemos criar formulários de acordo com os requisitos do negócio e concluir o funcionamento do aplicativo.

O mais importante antes da criação de qualquer aplicativo é entity mapping e projetar a estrutura do aplicativo.

O teste é um processo durante o qual a aplicação é conduzida de diferentes perspectivas para -

  • Encontre a lista de problemas
  • Encontre diferenças entre o resultado esperado e real, produção, estados, etc.
  • Compreenda a fase de implementação.
  • Encontre o aplicativo útil para fins realistas.

O objetivo do teste não é colocar o desenvolvedor em falta, mas fornecer ferramentas e melhorar a qualidade para estimar a integridade do aplicativo em um determinado momento.

O teste precisa ser planejado com antecedência. Isso exige definir a finalidade do teste, entender o escopo dos casos de teste, fazer a lista de requisitos de negócio e estar ciente dos riscos envolvidos nas diferentes fases do projeto.

O teste é definido como uma gama de aspectos a serem validados em um sistema ou aplicativo. A seguir está uma lista doscommon test approaches -

  • Unit testing- Isso geralmente é feito pelos próprios desenvolvedores. O objetivo é verificar se uma unidade de código funciona conforme o esperado ou não.

  • Usability testing- Os desenvolvedores geralmente podem esquecer que estão escrevendo um aplicativo para usuários finais que não têm conhecimento do sistema. O teste de usabilidade verifica os prós e contras do produto.

  • Functional/Acceptance testing - Enquanto o teste de usabilidade verifica se um aplicativo ou sistema é utilizável, o teste funcional garante que cada funcionalidade especificada seja implementada.

  • Load and performance testing- Isso é realizado para entender se o sistema pode se ajustar aos testes de carga e desempenho a serem realizados. Isso pode levar a mudanças no hardware, otimização de consultas SQL, etc.

  • Regression testing - Verifica que os sucessivos lançamentos de um produto não quebram nenhuma das funcionalidades anteriores.

  • Reliability and resilience testing - O teste de confiabilidade ajuda a validar a aplicação do sistema com a quebra de um ou vários componentes.

Teste de Unidade

Os aplicativos de fotoblog usam constantemente testes de unidade para verificar o seguinte -

  • Novas funcionalidades funcionam corretamente e conforme o esperado.
  • As funcionalidades existentes não são interrompidas pelo lançamento de um novo código.
  • Os defeitos são corrigidos e permanecem fixos.

O Python vem com um módulo de teste de unidade padrão que oferece uma abordagem diferente para o teste de unidade.

Teste de unidade

unittest é baseado em JUnit, um pacote de teste de unidade Java desenvolvido por Kent Beck e Erich Gamma. Os testes de unidade simplesmente retornam dados definidos. Objetos de simulação podem ser definidos. Esses objetos permitem o teste em uma interface de nosso design sem ter que depender do aplicativo geral. Eles também fornecem uma maneira de executar testes em modo de isolamento com outros testes incluídos.

Vamos definir uma classe fictícia da seguinte maneira -

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)

A explicação do código é a seguinte -

  • O módulo unittest deve ser importado para fornecer recursos de teste de unidade para a classe fornecida.

  • Uma classe deve ser criada pela subclasse de unittest.

  • Cada método no código acima começa com um teste de palavras. Todos esses métodos são chamados pelo manipulador de teste de unidade.

  • Os métodos assert / fail são chamados pelo caso de teste para gerenciar as exceções.

Considere isso como um exemplo para executar um caso de teste -

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

O resultado (saída) para executar o caso de teste será o seguinte -

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

Teste funcional

Uma vez que as funcionalidades do aplicativo começam a tomar forma de acordo com os requisitos, um conjunto de testes funcionais pode validar a exatidão do aplicativo em relação à especificação. No entanto, o teste deve ser automatizado para melhor desempenho, o que exigiria o uso de produtos de terceiros, como o Selenium.

CherryPy fornece classes auxiliares como funções integradas para facilitar a escrita de testes funcionais.

Teste de carga

Dependendo do aplicativo que você está escrevendo e de suas expectativas em termos de volume, pode ser necessário executar testes de carga e desempenho para detectar possíveis gargalos no aplicativo que o estão impedindo de atingir um determinado nível de desempenho.

Esta seção não detalha como conduzir um teste de desempenho ou carga, pois está fora do pacote FunkLoad.

O exemplo básico de FunkLoad é o seguinte -

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

Aqui está uma explicação detalhada do código acima -

  • O caso de teste deve ser herdado da classe FunkLoadTestCase para que o FunkLoad possa fazer seu trabalho interno de rastrear o que acontece durante o teste.

  • O nome da classe é importante porque FunkLoad procurará um arquivo com base no nome da classe.

  • Os casos de teste projetados têm acesso direto aos arquivos de configuração. Os métodos get () e post () são simplesmente chamados no servidor para obter a resposta.

Este capítulo se concentrará mais no SSL de aplicativo baseado em CherryPy habilitado através do servidor HTTP CherryPy embutido.

Configuração

Existem diferentes níveis de definições de configuração necessários em um aplicativo da web -

  • Web server - Configurações vinculadas ao servidor HTTP

  • Engine - Configurações associadas à hospedagem do motor

  • Application - Aplicativo que é usado pelo usuário

Desdobramento, desenvolvimento

A implantação do aplicativo CherryPy é considerada um método bastante fácil, onde todos os pacotes necessários estão disponíveis no caminho do sistema Python. Em um ambiente compartilhado hospedado na web, o servidor web residirá no front end, o que permite que o provedor de hospedagem execute as ações de filtragem. O servidor front-end pode ser Apache oulighttpd.

Esta seção apresentará algumas soluções para executar um aplicativo CherryPy por trás dos servidores 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)pode ser compatível com aplicativos baseados em CherryPy. Para ativar o suporte SSL, os seguintes requisitos devem ser atendidos:

  • Ter o pacote PyOpenSSL instalado no ambiente do usuário
  • Ter um certificado SSL e uma chave privada no servidor

Criação de um certificado e uma chave privada

Vamos lidar com os requisitos de certificado e chave privada -

  • Primeiro, o usuário precisa de uma chave privada -
openssl genrsa -out server.key 2048
  • Esta chave não é protegida por senha e, portanto, tem uma proteção fraca.
  • O seguinte comando será emitido -
openssl genrsa -des3 -out server.key 2048
  • O programa exigirá uma senha longa. Se sua versão do OpenSSL permitir que você forneça uma string vazia, faça isso. Caso contrário, insira uma senha longa padrão e remova-a da chave gerada da seguinte forma -

openssl rsa -in server.key -out server.key
  • A criação do certificado é a seguinte -
openssl req -new -key server.key -out server.csr
  • Este processo irá solicitar que você insira alguns detalhes. Para fazer isso, o seguinte comando deve ser emitido -

openssl x509 -req -days 60 -in server.csr -signkey
server.key -out server.crt
  • O certificado recém-assinado será válido por 60 dias.

O código a seguir mostra sua implementação -

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

A próxima etapa é iniciar o servidor; se você for bem-sucedido, verá a seguinte mensagem na tela -

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