API Star:一个 Python 3 的 API 框架
为了在 Python 中快速构建 API,我主要依赖于 Flask。最近我遇到了一个名为 “API Star” 的基于 Python 3 的新 API 框架。由于几个原因,我对它很感兴趣。首先,该框架包含 Python 新特点,如类型提示和 asyncio。而且它再进一步为开发人员提供了很棒的开发体验。我们很快就会讲到这些功能,但在我们开始之前,我首先要感谢 Tom Christie,感谢他为 Django REST Framework 和 API Star 所做的所有工作。
现在说回 API Star —— 我感觉这个框架很有成效。我可以选择基于 asyncio 编写异步代码,或者可以选择传统后端方式就像 WSGI 那样。它配备了一个命令行工具 —— apistar
来帮助我们更快地完成工作。它支持 Django ORM 和 SQLAlchemy,这是可选的。它有一个出色的类型系统,使我们能够定义输入和输出的约束,API Star 可以自动生成 API 的模式(包括文档),提供验证和序列化功能等等。虽然 API Star 专注于构建 API,但你也可以非常轻松地在其上构建 Web 应用程序。在我们自己构建一些东西之前,所有这些可能都没有意义的。
开始
我们将从安装 API Star 开始。为此实验创建一个虚拟环境是一个好主意。如果你不知道如何创建一个虚拟环境,不要担心,继续往下看。
pip install apistar
(译注:上面的命令是在 Python 3 虚拟环境下使用的)
如果你没有使用虚拟环境或者你的 Python 3 的 pip
名为 pip3
,那么使用 pip3 install apistar
代替。
一旦我们安装了这个包,我们就应该可以使用 apistar
命令行工具了。我们可以用它创建一个新项目,让我们在当前目录中创建一个新项目。
apistar new .
现在我们应该创建两个文件:app.py
,它包含主应用程序,然后是 test.py
,它用于测试。让我们来看看 app.py
文件:
from apistar import Include, Route
from apistar.frameworks.wsgi import WSGIApp as App
from apistar.handlers import docs_urls, static_urls
def welcome(name=None):
if name is None:
return {'message': 'Welcome to API Star!'}
return {'message': 'Welcome to API Star, %s!' % name}
routes = [
Route('/', 'GET', welcome),
Include('/docs', docs_urls),
Include('/static', static_urls)
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
在我们深入研究代码之前,让我们运行应用程序并查看它是否正常工作。我们在浏览器中输入 http://127.0.0.1:8080/
,我们将得到以下响应:
{"message": "Welcome to API Star!"}
如果我们输入:http://127.0.0.1:8080/?name=masnun
{"message": "Welcome to API Star, masnun!"}
同样的,输入 http://127.0.0.1:8080/docs/
,我们将看到自动生成的 API 文档。
现在让我们来看看代码。我们有一个 welcome
函数,它接收一个名为 name
的参数,其默认值为 None
。API Star 是一个智能的 API 框架。它将尝试在 url 路径或者查询字符串中找到 name
键并将其传递给我们的函数,它还基于其生成 API 文档。这真是太好了,不是吗?
然后,我们创建一个 Route
和 Include
实例的列表,并将列表传递给 App
实例。Route
对象用于定义用户自定义路由。顾名思义,Include
包含了在给定的路径下的其它 url 路径。
路由
路由很简单。当构造 App
实例时,我们需要传递一个列表作为 routes
参数,这个列表应该有我们刚才看到的 Route
或 Include
对象组成。对于 Route
,我们传递一个 url 路径,http 方法和可调用的请求处理程序(函数或者其他)。对于 Include
实例,我们传递一个 url 路径和一个 Routes
实例列表。
路径参数
我们可以在花括号内添加一个名称来声明 url 路径参数。例如 /user/{user_id}
定义了一个 url,其中 user_id
是路径参数,或者说是一个将被注入到处理函数(实际上是可调用的)中的变量。这有一个简单的例子:
from apistar import Route
from apistar.frameworks.wsgi import WSGIApp as App
def user_profile(user_id: int):
return {'message': 'Your profile id is: {}'.format(user_id)}
routes = [
Route('/user/{user_id}', 'GET', user_profile),
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
如果我们访问 http://127.0.0.1:8080/user/23
,我们将得到以下响应:
{"message": "Your profile id is: 23"}
但如果我们尝试访问 http://127.0.0.1:8080/user/some_string
,它将无法匹配。因为我们定义了 user_profile
函数,且为 user_id
参数添加了一个类型提示。如果它不是整数,则路径不匹配。但是如果我们继续删除类型提示,只使用 user_profile(user_id)
,它将匹配此 url。这也展示了 API Star 的智能之处和利用类型和好处。
包含/分组路由
有时候将某些 url 组合在一起是有意义的。假设我们有一个处理用户相关功能的 user
模块,将所有与用户相关的 url 分组在 /user
路径下可能会更好。例如 /user/new
、/user/1
、/user/1/update
等等。我们可以轻松地在单独的模块或包中创建我们的处理程序和路由,然后将它们包含在我们自己的路由中。
让我们创建一个名为 user
的新模块,文件名为 user.py
。我们将以下代码放入这个文件:
from apistar import Route
def user_new():
return {"message": "Create a new user"}
def user_update(user_id: int):
return {"message": "Update user #{}".format(user_id)}
def user_profile(user_id: int):
return {"message": "User Profile for: {}".format(user_id)}
user_routes = [
Route("/new", "GET", user_new),
Route("/{user_id}/update", "GET", user_update),
Route("/{user_id}/profile", "GET", user_profile),
]
现在我们可以从 app 主文件中导入 user_routes
,并像这样使用它:
from apistar import Include
from apistar.frameworks.wsgi import WSGIApp as App
from user import user_routes
routes = [
Include("/user", user_routes)
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
现在 /user/new
将委托给 user_new
函数。
访问查询字符串/查询参数
查询参数中传递的任何参数都可以直接注入到处理函数中。比如 url /call?phone=1234
,处理函数可以定义一个 phone
参数,它将从查询字符串/查询参数中接收值。如果 url 查询字符串不包含 phone
的值,那么它将得到 None
。我们还可以为参数设置一个默认值,如下所示:
def welcome(name=None):
if name is None:
return {'message': 'Welcome to API Star!'}
return {'message': 'Welcome to API Star, %s!' % name}
在上面的例子中,我们为 name
设置了一个默认值 None
。
注入对象
通过给一个请求程序添加类型提示,我们可以将不同的对象注入到视图中。注入请求相关的对象有助于处理程序直接从内部访问它们。API Star 内置的 http
包中有几个内置对象。我们也可以使用它的类型系统来创建我们自己的自定义对象并将它们注入到我们的函数中。API Star 还根据指定的约束进行数据验证。
让我们定义自己的 User
类型,并将其注入到我们的请求处理程序中:
from apistar import Include, Route
from apistar.frameworks.wsgi import WSGIApp as App
from apistar import typesystem
class User(typesystem.Object):
properties = {
'name': typesystem.string(max_length=100),
'email': typesystem.string(max_length=100),
'age': typesystem.integer(maximum=100, minimum=18)
}
required = ["name", "age", "email"]
def new_user(user: User):
return user
routes = [
Route('/', 'POST', new_user),
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
现在如果我们发送这样的请求:
curl -X POST \
http://127.0.0.1:8080/ \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{"name": "masnun", "email": "masnun@gmail.com", "age": 12}'
猜猜发生了什么?我们得到一个错误,说年龄必须等于或大于 18。类型系允许我们进行智能数据验证。如果我们启用了 docs
url,我们还将自动记录这些参数。
发送响应
如果你已经注意到,到目前为止,我们只可以传递一个字典,它将被转换为 JSON 并作为默认返回。但是,我们可以使用 apistar
中的 Response
类来设置状态码和其它任意响应头。这有一个简单的例子:
from apistar import Route, Response
from apistar.frameworks.wsgi import WSGIApp as App
def hello():
return Response(
content="Hello".encode("utf-8"),
status=200,
headers={"X-API-Framework": "API Star"},
content_type="text/plain"
)
routes = [
Route('/', 'GET', hello),
]
app = App(routes=routes)
if __name__ == '__main__':
app.main()
它应该返回纯文本响应和一个自定义标响应头。请注意,content
应该是字节,而不是字符串。这就是我编码它的原因。
继续
我刚刚介绍了 API Star 的一些特性,API Star 中还有许多非常酷的东西,我建议通过 Github Readme 文件来了解这个优秀框架所提供的不同功能的更多信息。我还将尝试在未来几天内介绍关于 API Star 的更多简短的,集中的教程。
原文地址:https://linux.cn/article-9987-1.html
API Star:一个 Python 3 的 API 框架的更多相关文章
- 【ASP.NET Web API教程】1.1 第一个ASP.NET Web API
Your First ASP.NET Web API (C#)第一个ASP.NET Web API(C#) By Mike Wasson|January 21, 2012作者:Mike Wasson ...
- 【ASP.NET Web API教程】2.3 与实体框架一起使用Web API
原文:[ASP.NET Web API教程]2.3 与实体框架一起使用Web API 2.3 Using Web API with Entity Framework 2.3 与实体框架一起使用Web ...
- Python几种主流框架
从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框架 Djang ...
- python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...
- Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...
- (41)zabbix监控api接口性能及可用性 天气预报api为例
现在各种应用都走api,例如淘宝,天气预报等手机.pad客户端都是走api的,那么平时也得对这些api做监控了.怎么做呢?zabbix的web监控是不二选择了.今天就以天气预报api作为一个例子. 天 ...
- 如何创建一个验证请求的API框架
开发一款成功软件的关键是良好的架构设计.优秀的设计不仅允许开发人员轻松地编写新功能,而且还能丝滑的适应各种变化. 好的设计应该关注应用程序的核心,即领域. 不幸的是,这很容易将领域与不属于这一层的职 ...
- 选择一个 Python Web 框架:Django vs Flask vs Pyramid
Pyramid, Django, 和 Flask都是优秀的框架,为项目选择其中的哪一个都是伤脑筋的事.我们将会用三种框架实现相同功能的应用来更容易的对比三者.也可以直接跳到框架实战(Framework ...
- Windows API Hooking in Python
catalogue . 相关基础知识 . Deviare API Hook Overview . 使用ctypes调用Windows API . pydbg . winappdbg . dll inj ...
随机推荐
- Spring学习(五)事务管理
Spring 事务管理: 一.事务概念: 1.什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的 ...
- 027 Remove Element 移除元素
给定一个数组和一个值,在这个数组中原地移除指定值和返回移除后新的数组长度.不要为其他数组分配额外空间,你必须使用 O(1) 的额外内存原地修改这个输入数组.元素的顺序可以改变.超过返回的新的数组长度以 ...
- Sort HDU - 5884 哈夫曼权值O(n)
http://acm.hdu.edu.cn/showproblem.php?pid=5884 原来求一次哈夫曼可以有O(n)的做法. 具体是,用两个队列,一个保存原数组,一个保存k个节点合并的数值,然 ...
- Unity UGUI暂停按钮切换图片代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...
- (转)Linux网络接口配置文件ifcfg-eth0解析
原文:http://blog.51cto.com/xtbao/1671739 https://www.cnblogs.com/arvintang/p/5990599.html http://blog. ...
- QT学习小demo之LightMD(MarkDown编辑器)
很早之前就有了写一个类似Windows记事本的想法,加上最近也刚好在学编译原理,所以就想把两者结合起来,于是就打算结合MarkDown,开发一款MarkDown编辑器. 不过由于我之前一直使用的是Ja ...
- lambda匿名函数,sorted排序,filter()筛选,map()映射
一丶匿名函数 语法: 函数名 = lambda参数:返回值 # 普通的正常的函数 def func(n): return n * n ret = func(9) print(ret) # 匿名函数 a ...
- HTTP缓存技术,304和200有何区别
为什么有的缓存是 200 OK (from cache),有的缓存是 304 Not Modified 呢?很简单,看运维是否移除了 Entity Tag.移除了,就总是 200 OK (from c ...
- Java集合框架—List
Collection |--List:元素是有序的,元素可以重复.因为该集合体系有索引. |--ArrayList:底层的数据结构使用的是数组结构.特点:查询速度很快.但是增删稍慢.线程不同步. |- ...
- shell实现mysql数据库备份
#!/bin/bash DB_USER="root" #数据库用户名 DB_PASS="12345678" #数据库密码 BACK_DIR="/bac ...