使用FastAPI的APIRouter路由子模块时遇参数错误问题求助
问题描述
main.py中编写的FastAPI代码里,/test接口可正常访问,但在default.py通过APIRouter定义的/test2接口调用时抛出TypeError,提示test2() takes 0 positional arguments but 1 was given,根路由/可正常工作。
main.py代码
from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.middleware.gzip import GZipMiddleware from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles from my_app.web.views import default app = FastAPI() app.add_middleware(GZipMiddleware, minimum_size=500) app.include_router(default.router) #app.include_router(data_mgr_view.router) app.mount("/static", StaticFiles(directory="static"), name="static") app.mount("/templates", Jinja2Templates(directory="templates"), name="templates") @app.get('/test') async def test(): return "test successful"
default.py代码
import sys, traceback import pandas as pd from fastapi import APIRouter, Request, Query from my_app.web.models.response_data import ResponseData from my_app.data.providers.internals_provider import MktInternalsProvider from my_app.config import tmplts router = APIRouter(prefix="") @router.route('/') async def root(request: Request): context = {"title":"Playground", "content":f"Place for my charts, studies, etc..."} return tmplts.TemplateResponse(request=request, name="index.html", context=context) @router.route('/test2') async def test2(): return "test2 success"
报错栈
Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 411, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 123, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 186, in __call__ raise exc File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 164, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 24, in __call__ await responder(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/gzip.py", line 44, in __call__ await self.app(scope, receive, self.send_with_gzip) File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 65, in __call__ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app raise exc File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 756, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 776, in app await route.handle(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 297, in handle await self.app(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 77, in app await wrap_app_handling_exceptions(app, request)(scope, receive, send) File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app raise exc File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 72, in app response = await func(request) ^^^^^^^^^^^^^ TypeError: test2() takes 0 positional arguments but 1 was given
解决方案
原因
使用@router.route()装饰器时,FastAPI(底层基于Starlette)会自动向视图函数传递request对象,无论你是否需要该参数。而test2函数没有定义接收这个参数,因此触发TypeError。
解决方法二选一:
- 为test2添加request参数(即使不用)
修改default.py中的test2函数:
@router.route('/test2') async def test2(request: Request): return "test2 success"
- 改用HTTP方法专用装饰器
和main.py中的/test接口一样,使用@router.get()(或对应HTTP方法的装饰器,如post、put等),这种情况下如果不需要request,可不定义参数:
@router.get('/test2') async def test2(): return "test2 success"
内容的提问来源于stack exchange,提问作者mike01010
相关产品推荐
相关产品推荐

