CherryPy - Web 服务

Web 服务是一组基于 Web 的组件,有助于在应用程序或系统之间交换数据,其中还包括开放协议和标准。它可以在网上发布,使用和发现。

Web 服务有各种类型,如 RWS(RESTfUL Web 服务),WSDL,SOAP 等等。

REST - Representational State Transfer

一种远程访问协议,它将状态从客户端传输到服务器,可用于操作状态而不是调用远程过程。

  • 没有定义任何特定的编码或结构以及返回有用错误消息的方法。

  • 使用 HTTP 动作来执行状态转移操作。

  • 使用 URL 唯一标识资源。

  • 它不是 API,而是 API 传输层。

REST 维护网络上资源的命名,并提供统一的机制来对这些资源执行操作。每个资源由至少一个标识符标识。如果 REST 基础结构是以 HTTP 为基础实现的,则这些标识符称为统一资源标识符(URI)

以下是 URI 集的两个常见子集 -

子集 完整形式 例子
URL 统一资源定位器 http://www.gmail.com/
URN 统一资源名称 urn:isbn:0-201-71088-9 urn:uuid:13e8cf26-2a25-11db-8693-000ae4ea7d46

在了解 CherryPy 架构的实现之前,让我们关注 CherryPy 的架构。

CherryPy 包括以下三个组件 -

  • cherrypy.engine - 它控制进程启动/拆卸和事件处理。

  • cherrypy.server - 它配置和控制 WSGI 或 HTTP 服务器。

  • cherrypy.tools - 与处理 HTTP 请求正交的实用工具箱。

REST 接口通过 CherryPy

RESTful Web 服务在以下帮助下实现 CherryPy 架构的每个部分 -

  • 认证
  • 授权
  • 结构体
  • 封装
  • 错误处理

认证

身份验证有助于验证与我们交互的用户。CherryPy 包含处理每种身份验证方法的工具。

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)

上述函数 authenticate() 将有助于验证客户端或用户的存在。内置工具有助于系统地完成该过程。

授权

授权有助于通过 URI 维护流程的健全性。该过程还有助于通过用户令牌引线变形对象。

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

内置的授权工具有助于系统地处理例程,如前面的示例所述。

结构体

维护 API 结构有助于减少映射应用程序 URI 的工作量。始终需要保持 API 可被发现和清洁。CherryPy 框架的 API 的基本结构应该如下 -

  • 帐户和用户
  • 自动应答
  • 联系
  • 文件
  • 列表和字段
  • 消息和批处理

封装

封装有助于创建轻量级,人类可读且可供各种客户端访问的 API。项目列表以及创建,检索,更新和删除需要封装 API。

错误处理

如果 API 无法以特定的本能执行,此过程将管理错误(如果有)。例如,400 表示错误请求,403 表示未授权请求。

请考虑以下内容作为数据库,验证或应用程序错误的示例。

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

上面的代码将产生以下输出 -

错误处理

由于内置的访问工具,通过 CherryPy 可以轻松管理 API(应用程序编程接口)。

HTTP 方法

对资源进行操作的 HTTP 方法列表如下 -

原子发布协议(Atom Publishing Protocol - APP)

APP 已经从 Atom 社区出现,作为 HTTP 之上的应用程序级协议,允许发布和编辑 Web 资源。APP 服务器和客户端之间的消息单元基于 Atom XML 文档格式。

Atom 发布协议使用 HTTP 及其机制和 Atom XML 文档格式作为消息单元,定义 APP 服务和用户代理之间的一组操作。

APP 首先定义服务文档,该服务文档向用户代理提供 APP 服务所服务的不同集合的 URI。

让我们举个例子来说明 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 指定如何使用 HTTP 方法对集合成员或集合本身执行基本 CRUD 操作,如下表所述 -

操作 HTTP 方法 状态代码 内容
Retrieve GET 200 表示资源的 Atom 条目
Create POST 201 通过 Location 和 Content-Location 标头创建的新资源的 URI
Update PUT 200 表示资源的 Atom 条目
Delete DELETE 200 没有