媒体

Falcon允许轻松和定制的互联网媒体类型处理。默认情况下,Falcon只为JSON和HTML(URL编码和多部分)表单启用处理程序。但是,可以通过 falcon.RequestOptionsfalcon.ResponseOptions 在您的 falcon.App .

注解

为了避免不必要的开销,Falcon将只在第一次引用Media属性时处理请求媒体。一旦被引用,它将使用缓存的结果进行后续交互。

使用

如果要创建JSON API,则需要零配置。简单使用 get_media()media (WSGI),或 get_media()media (ASGI)让Falcon帮你做重活。

import falcon


class EchoResource:
    def on_post(self, req, resp):
        # Deserialize the request body based on the Content-Type
        #   header in the request, or the default media type
        #   when the Content-Type header is generic ('*/*') or
        #   missing.
        obj = req.get_media()

        message = obj.get('message')

        # The framework will look for a media handler that matches
        #   the response's Content-Type header, or fall back to the
        #   default media type (typically JSON) when the app does
        #   not explicitly set the Content-Type header.
        resp.media = {'message': message}
        resp.status = falcon.HTTP_200
import falcon


class EchoResource:
    async def on_post(self, req, resp):
        # Deserialize the request body. Note that the ASGI version
        #   of this method must be awaited.
        obj = await req.get_media()

        message = obj.get('message')

        # The framework will look for a media handler that matches
        #   the response's Content-Type header, or fall back to the
        #   default media type (typically JSON) when the app does
        #   not explicitly set the Content-Type header.
        resp.media = {'message': message}
        resp.status = falcon.HTTP_200

警告

一次 falcon.Request.get_media()falcon.asgi.Request.get_media() 对请求调用,它将使用请求的正文流。

正在验证媒体

Falcon目前只提供一个JSON模式媒体验证程序;但是,JSON模式非常通用,可以用来验证JSON也支持的任何反序列化媒体类型(如dicts、list等)。

falcon.media.validators.jsonschema.validate(req_schema=None, resp_schema=None)[源代码]

用于验证的装饰器 req.media 使用JSON模式。

这个装饰器通过 jsonschema PYPI提供的包。语义验证通过 格式 已为实现的默认检查程序启用关键字 jsonschema.FormatChecker .

注解

这个 jsonschema `包必须单独安装才能使用此装饰器,因为默认情况下Falcon不安装它。

json-schema.org 有关定义兼容字典的详细信息。

参数
  • req_schema (dict, optional) -- 遵循JSON模式规范的字典。将根据此架构验证请求。

  • resp_schema (dict, optional) -- 遵循JSON模式规范的字典。将根据此架构验证响应。

示例

from falcon.media.validators import jsonschema

# -- snip --

@jsonschema.validate(my_post_schema)
def on_post(self, req, resp):

# -- snip --

如果JSON模式不满足您的需求,那么定制验证器的实现方式可能与上面的方法类似。

内容类型协商

Falcon目前只支持开箱即用的部分协商。默认情况下,当 get_media() 方法或 media 属性时,框架尝试基于 Content-Type 标题值。Falcon没有提供的缺失链接是 Accept 由用户提供的头和 Content-Type 在响应上设置标头。

如果您确实需要完整的协商,那么使用中间件很容易弥合这一差距。下面是一个如何做到这一点的示例:

class NegotiationMiddleware:
    def process_request(self, req, resp):
        resp.content_type = req.accept
class NegotiationMiddleware:
    async def process_request(self, req, resp):
        resp.content_type = req.accept

替换默认处理程序

创建应用程序对象时,可以添加或完全替换所有处理程序。例如,假设您要编写一个发送和接收的API MessagePack . 我们可以通过告诉Falcon API我们希望默认的媒体类型 application/msgpack 然后创建一个新的 Handlers 对象,指定所需的媒体类型和可以处理该数据的处理程序。

import falcon
from falcon import media


handlers = media.Handlers({
    'application/msgpack': media.MessagePackHandler(),
})

app = falcon.App(media_type='application/msgpack')

app.req_options.media_handlers = handlers
app.resp_options.media_handlers = handlers

或者,如果您想在不删除默认处理程序的情况下添加其他处理程序,则可以按如下方式轻松完成:

import falcon
from falcon import media


extra_handlers = {
    'application/msgpack': media.MessagePackHandler(),
}

app = falcon.App()

app.req_options.media_handlers.update(extra_handlers)
app.resp_options.media_handlers.update(extra_handlers)

支持的处理程序类型

class falcon.media.JSONHandler(dumps=None, loads=None)

JSON媒体处理程序。

此处理程序使用Python的标准 json 库在默认情况下,但可以根据需要轻松配置为使用许多第三方JSON库中的任何一个。例如,通过使用替代库,您通常可以在cpython下实现显著的性能提升。在这方面的好选择包括 orjsonpython-rapidjsonmujson .

注解

如果您要部署到Pypy,我们建议您坚持使用标准库的JSON实现,因为与第三方库相比,它在大多数情况下都会更快。

覆盖默认的JSON实现只是指定所需的 dumpsloads 功能::

import falcon
from falcon import media

import rapidjson

json_handler = media.JSONHandler(
    dumps=rapidjson.dumps,
    loads=rapidjson.loads,
)
extra_handlers = {
    'application/json': json_handler,
}

api = falcon.API()
api.req_options.media_handlers.update(extra_handlers)
api.resp_options.media_handlers.update(extra_handlers)

默认情况下, ensure_ascii 传递给 json.dumps 功能。如果您覆盖 dumps 函数,需要显式设置 ensure_asciiFalse 以便将Unicode字符序列化为UTF-8。这很容易用 functools.partial 应用所需的关键字参数。实际上,您可以使用相同的技术自定义 dumpsloads 功能::

from functools import partial

from falcon import media
import rapidjson

json_handler = media.JSONHandler(
    dumps=partial(
        rapidjson.dumps,
        ensure_ascii=False, sort_keys=True
    ),
)
关键字参数
  • dumps (func) -- 在序列化JSON响应时使用的函数。

  • loads (func) -- 反序列化JSON请求时使用的函数。

class falcon.media.MessagePackHandler

使用生成的处理程序 msgpack 模块。

此处理程序使用 msgpack.unpackb()msgpack.packb() .消息包 bin 类型用于区分Unicode字符串 (str 在python 3上, unicode 在python 2)和字节字符串上 (bytes 在python 2/3上,或 str 在python 2上)。

注解

此处理程序需要额外的 msgpack 软件包(0.5.2或更高版本),必须安装在 falcon 来自Pypi:

$ pip install msgpack

自定义处理程序类型

如果Falcon没有支持您的用例的Internet媒体类型处理程序,您可以使用Falcon提供的抽象基类轻松实现自己的处理程序:

class falcon.media.BaseHandler

Internet媒体类型处理程序的抽象基类

abstract deserialize(stream, content_type, content_length)

反序列化 falcon.Request 身体。

参数
  • stream (object) -- 输入要反序列化的数据。

  • content_type (str) -- 请求内容的类型。

  • content_length (int) -- 请求内容的长度。

返回

反序列化对象。

返回类型

object

abstract serialize(media, content_type)

在上序列化媒体对象 falcon.Response

参数
  • media (object) -- 可序列化对象。

  • content_type (str) -- 响应内容的类型。

返回

从输入对象得到的序列化字节。

返回类型

bytes

小技巧

为了在 Falcon app ,则必须将类的实例添加到应用程序的媒体处理程序(在中指定) RequestOptionsResponseOptions ,分别)。

参见: 替换默认处理程序 .

处理程序映射

class falcon.media.Handlers(initial=None)

管理Internet媒体类型处理程序的类似字典的对象。

媒体类型常量

这个 falcon 模块为常见的媒体类型字符串提供了许多常量,包括:

falcon.MEDIA_JSON
falcon.MEDIA_MSGPACK
falcon.MEDIA_MULTIPART
falcon.MEDIA_URLENCODED
falcon.MEDIA_YAML
falcon.MEDIA_XML
falcon.MEDIA_HTML
falcon.MEDIA_JS
falcon.MEDIA_TEXT
falcon.MEDIA_JPEG
falcon.MEDIA_PNG
falcon.MEDIA_GIF