Sanic 处理程序简介#
处理程序(handlers) 也被称为视图(view)。在 Sanic 中,处理程序是至少接受 sanic.request.Request
实例作为参数并返回 sanic.response.HTTPResponse
实例或执行相同操作的协程的任何可调用程序。
它是一个同步或异步函数。
def i_am_a_handler(request):
return HTTPResponse()
async def i_am_ALSO_a_handler(request):
return HTTPResponse()
处理程序的工作是响应端点并做一些事情。这是您的大部分业务逻辑的去处。
重要
简单的基于函数的处理程序#
创建路由处理程序最常用的方法是修饰该函数。它创建了视觉上简单的路由定义标识。
from sanic import text, Sanic
app = Sanic("Demo")
@app.get("/foo")
async def foo_handler(request):
return text("I said foo!")
下面的处理器的名字是:"foo_handler"
:
@app.get("/foo")
async def foo_handler(request):
return text("I said foo!")
---------------------------------------------------------------------------
RouteExists Traceback (most recent call last)
Cell In[2], line 2
1 @app.get("/foo")
----> 2 async def foo_handler(request):
3 return text("I said foo!")
File /opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/sanic/mixins/routes.py:209, in RouteMixin.route.<locals>.decorator(handler)
206 handler.is_stream = stream
208 if apply:
--> 209 self._apply_route(route, overwrite=overwrite)
211 if static:
212 return route, handler
File /opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/sanic/app.py:618, in Sanic._apply_route(self, route, overwrite)
615 ctx = params.pop("route_context")
617 with self.amend():
--> 618 routes = self.router.add(**params)
619 if isinstance(routes, Route):
620 routes = [routes]
File /opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/sanic/router.py:148, in Router.add(self, uri, methods, handler, host, strict_slashes, stream, ignore_body, version, name, unquote, static, version_prefix, overwrite, error_format)
141 if len(hosts) > 1:
142 ident = (
143 f"{name}_{host.replace('.', '_')}"
144 if name
145 else "__unnamed__"
146 )
--> 148 route = super().add(**params) # type: ignore
149 route.extra.ident = ident
150 route.extra.ignore_body = ignore_body
File /opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/sanic_routing/router.py:252, in BaseRouter.add(self, path, handler, methods, name, requirements, strict, unquote, overwrite, append, priority)
250 if route.segments in routes:
251 existing_group = routes[route.segments]
--> 252 group.merge(existing_group, overwrite, append)
254 routes[route.segments] = group
256 if name:
File /opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/sanic_routing/group.py:168, in RouteGroup.merge(self, group, overwrite, append)
156 if (
157 current_route == other_route
158 or (
(...)
165 )
166 ) and not append:
167 if not overwrite:
--> 168 raise RouteExists(
169 f"Route already registered: {self.raw_path} "
170 f"[{','.join(self.methods)}]"
171 )
172 else:
173 _routes.append(other_route)
RouteExists: Route already registered: foo [GET]
但是,您可以通过将 name
参数传递给装饰器来覆盖这一点。
# 处理器名字改为 "foo"
@app.get("/foo", name="foo")
async def foo_handler(request):
return text("I said foo!")
事实上,有时您必须提供名称。例如,如果在同一个函数上使用两个装饰器,则需要为其中至少一个提供名称。
如果你不这样做,你会得到一个错误,你的应用程序将无法启动。名称在应用程序中必须是唯一的。
# Two handlers, same function,
# different names:
# - "foo_arg"
# - "foo"
@app.get("/foo/<arg>", name="foo_arg")
@app.get("/foo")
async def foo(request, arg=None):
return text("I said foo!")