aiohttp官方教程翻译(4)—— 服务器端编程之快速开始

Web Server Quickstart


1、Run a Simple Web Server(启动一个简单的Web服务器)

为了使一个web服务器生效,首先创建一个请求处理器

一个请求处理器必须是一个接受Request实例作为他唯一参数并且返回一个Response实例的协程:

from aiohttp import web

async def hello(request):
    return web.Response(text="Hello, world")

之后,创建一个Application实例并在特定的HTTP方法和路径上注册请求处理器:

app = web.Application()
app.add_routes([web.get('/', hello)])

然后,通过 run_app() 运行(最好指定下端口,不然可能会有进程已经占用默认端口):

web.run_app(app,host='127.0.0.1', port=9000)

又或者你更愿意使用route装饰器创建一个route table 并注册一个web处理器:

routes = web.RouteTableDef()

@routes.get('/')
async def hello(request):
    return web.Response(text="Hello, world")

app = web.Application()
app.add_routes(routes)
web.run_app(app)

两种方法本质上无区别,关键在于你喜欢上面的那种Django风格,还是下面的Flask风格

结果可以看到在127.0.0.1:9000上返回的hello world文本


2、Command Line Interface (CLI)(命令行界面)

aiohttp.web能够生效一个CLI给基于TCP/IP的程序快速提供给服务

$ python -m aiohttp.web -H localhost -P 8080 package.module:init_func
def init_func(argv):
    app = web.Application()
    app.router.add_get("/", index_handler)
    return app

3、Handler(句柄)(ps:和第一节东西差不多)

一个句柄必须是一个接受Request实例作为他唯一参数并且返回一个 StreamResponse实例的协程:

async def handler(request):
    return web.Response()

使用Application.add_routes()进行绑定:

app.add_routes([web.get('/', handler),
                web.post('/post', post_handler),
                web.put('/put', put_handler)])

或者使用route装饰器:

routes = web.RouteTableDef()

@routes.get('/')
async def get_handler(request):
    ...

@routes.post('/post')
async def post_handler(request):
    ...

@routes.put('/put')
async def put_handler(request):
    ...

app.add_routes(routes)

未知HTTP方法也是被 route() 或 RouteTableDef.route()支持的,允许一个Handler处理任何HTTP方法:

app.add_routes([web.route('*', '/path', all_handler)])

默认情况下,使用GET方法添加的端点将接受HEAD请求并返回与GET请求相同的响应头。你还可以拒绝路由上的HEAD请求:

web.get('/', handler, allow_head=False)

4、Resources and Routes(资源与路径)

内部路径由 Application.router (UrlDispatcher实例)提供。
路由器是一个资源列表。
资源是路由表中与请求的URL相对应的条目。
反过来,资源至少有一个路由。
Route对应于通过调用web handler来处理HTTP方法。
因此,当你添加路由时,resource对象将在底层创建。
库的实现合并同一路径的所有后续路由添加,为所有HTTP方法添加唯一的资源。
这儿有两个例子:

app.add_routes([web.get('/path1', get_1),
                web.post('/path1', post_1),
                web.get('/path2', get_2),
                web.post('/path2', post_2)]
app.add_routes([web.get('/path1', get_1),
                web.get('/path2', get_2),
                web.post('/path2', post_2),
                web.post('/path1', post_1)]

如果你认为第一个是更优化的,那么你就理解了。

(ps:加一下笔者的理解,第一种写法更能方便看出来不同路径方法的对应关系,防止重复被覆盖)


5、Variable Resources(可变资源)

资源也可以拥有可变路径,例如’/a/{name}/c’ 可以匹配’/a/b/c’, ‘/a/1/c’, and '/a/etc/c’等。
可变的部分类似这种形式{identifier},并且使用 Request.match_info进行匹配:

@routes.get('/{name}')
async def variable_handler(request):
    return web.Response(
        text="Hello, {}".format(request.match_info['name']))

默认情况下,每个部分都匹配正则表达式[^{}/]+。

当然也可以使用如下的方式:

web.get(r'/{name:\d+}', handler)

6、Reverse URL Constructing using Named Resources(使用命名资源实现URL反转)

路径可以用以下方式命名:

@routes.get('/root', name='root')
async def handler(request):
    ...

然后可以用来访问和构建该资源的URL:

url == request.app.router['root'].url_for().with_query({"a": "b", "c": "d"})
assert url == URL('/root?a=b&c=d')

一个更有趣的例子是构建可变资源的URL:

app.router.add_resource(r'/{user}/info', name='user-info')

在这种情况下,也可以传递部分路径:

url = request.app.router['user-info'].url_for(user='john_doe')
url_with_qs = url.with_query("a=b")
assert url_with_qs == '/john_doe/info?a=b'

7、Organizing Handlers in Classes(通过类的方法组织句柄)

正如上面所展示的,句柄可以使用第一类对象协程:

async def hello(request):
    return web.Response(text="Hello, world")

app.router.add_get('/', hello)

但是开发者为了方便也可以自己编写一个:

class Handler:

    def __init__(self):
        pass

    async def handle_intro(self, request):
        return web.Response(text="Hello, world")

    async def handle_greeting(self, request):
        name = request.match_info.get('name', "Anonymous")
        txt = "Hello, {}".format(name)
        return web.Response(text=txt)

handler = Handler()
app.add_routes([web.get('/intro', handler.handle_intro),
                web.get('/greet/{name}', handler.handle_greeting)]

to be modified

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值