基于falcon构建的优雅Python REST工具包
项目描述
graceful
graceful
是一个基于 falcon 框架构建的优雅Python REST工具包。它高度受到 Django REST framework 的启发 - 主要受对象序列化方式的影响,但在此更注重API的自描述性。
特性
- 通用类用于列表和单个对象资源
- 简单但可扩展的分页
- 简单但可扩展的认证和授权
- 结构化响应,内容/元数据分离
- 声明性字段和参数
- 自描述一切:API描述在Python和通过
OPTIONS
请求中均可访问 - 无痛苦验证
- 100% 测试覆盖率
- falcon>=0.3.0 (已测试至1.4.x)
- 仅限python3 (已测试从3.3到3.6)
优雅的社区正在开始成长,但我们还没有任何邮件列表。之前在 Librelist 上有一个,但没有人使用它,看起来librelist已经死亡(参见GitHub问题 #36)。目前让我们使用gitter聊天,直到我们决定新的方案。聊天在此 处 可用。
仅限python3
重要: graceful
仅限python3,因为 目前 是忘记python2的好时机。没有计划使 graceful
与python2兼容,尽管使用现有工具(如six)这样做相当简单。
用法
有关扩展教程和更多信息,请参阅文档中包含的指南。
无论如何,这里有一个使用 graceful
制作的简单工作 API 示例。
import falcon
from graceful.serializers import BaseSerializer
from graceful.fields import IntField, RawField
from graceful.parameters import StringParam
from graceful.resources.generic import (
RetrieveAPI,
PaginatedListAPI,
)
api = application = falcon.API()
# lets pretend that this is our backend storage
CATS_STORAGE = [
{"id": 0, "name": "kitty", "breed": "saimese"},
{"id": 1, "name": "lucie", "breed": "maine coon"},
{"id": 2, "name": "molly", "breed": "sphynx"},
]
# this is how we represent cats in our API
class CatSerializer(BaseSerializer):
id = IntField("cat identification number", read_only=True)
name = RawField("cat name")
breed = RawField("official breed name")
class Cat(RetrieveAPI):
"""
Single cat identified by its id
"""
serializer = CatSerializer()
def get_cat(self, cat_id):
try:
return [
cat for cat in CATS_STORAGE if cat['id'] == int(cat_id)
][0]
except IndexError:
raise falcon.HTTPNotFound
def retrieve(self, params, meta, **kwargs):
cat_id = kwargs['cat_id']
return self.get_cat(cat_id)
class CatList(PaginatedListAPI):
"""
List of all cats in our API
"""
serializer = CatSerializer()
breed = StringParam("set this param to filter cats by breed")
def list(self, params, meta, **kwargs):
if 'breed' in params:
filtered = [
cat for cat in CATS_STORAGE
if cat['breed'] == params['breed']
]
return filtered
else:
return CATS_STORAGE
api.add_route("/v1/cats/{cat_id}", Cat())
api.add_route("/v1/cats/", CatList())
假设此代码位于名为 example.py
的 Python 模块中。现在使用 gunicorn 运行它。
gunicorn -b localhost:8888 example
然后您就可以查询它了(这里使用出色的 httpie 工具)。
$ http localhost:8888/v0/cats/?breed=saimese
HTTP/1.1 200 OK
Connection: close
Date: Tue, 16 Jun 2015 08:43:05 GMT
Server: gunicorn/19.3.0
content-length: 116
content-type: application/json
{
"content": [
{
"breed": "saimese",
"id": 0,
"name": "kitty"
}
],
"meta": {
"params": {
"breed": "saimese",
"indent": 0
}
}
}
或者通过发出 OPTIONS
请求来访问 API 描述。
$ http OPTIONS localhost:8888/v0/cats
HTTP/1.1 200 OK
Connection: close
Date: Tue, 16 Jun 2015 08:40:00 GMT
Server: gunicorn/19.3.0
allow: GET, OPTIONS
content-length: 740
content-type: application/json
{
"details": "List of all cats in our API",
"fields": {
"breed": {
"details": "official breed name",
"label": null,
"spec": null,
"type": "string"
},
"id": {
"details": "cat identification number",
"label": null,
"spec": null,
"type": "int"
},
"name": {
"details": "cat name",
"label": null,
"spec": null,
"type": "string"
}
},
"methods": [
"GET",
"OPTIONS"
],
"name": "CatList",
"params": {
"breed": {
"default": null,
"details": "set this param to filter cats by breed",
"label": null,
"required": false,
"spec": null,
"type": "string"
},
"indent": {
"default": "0",
"details": "JSON output indentation. Set to 0 if output should not be formated.",
"label": null,
"required": false,
"spec": null,
"type": "integer"
}
},
"path": "/v0/cats",
"type": "list"
}
贡献
任何贡献都受欢迎。问题、建议、拉取请求——无论什么。在提交拉取请求之前,您应该了解指导此项目发展的简短规则集。
- 只有通过 CI 构建(Travis)通过的请求才会被合并。
- 代码在构建期间使用
flakes8
和pydocstyle
进行检查,这意味着强制符合 PEP-8 和 PEP-257。 - 不会合并降低覆盖率的变化。
一点:如果您提交了 PR,请不要重新基础它,除非您被明确要求这样做。审查突然重写了历史记录的拉取请求让我非常沮丧。
许可
请参阅 LICENSE
文件。
项目详情
下载文件
下载您平台的文件。如果您不确定要选择哪一个,请了解更多关于 安装包 的信息。
源分发
graceful-0.6.3.tar.gz (32.6 kB 查看哈希值)
构建分发
graceful-0.6.3-py2.py3-none-any.whl (64.0 kB 查看哈希值)