admin管理员组文章数量:1123930
I started from the example shown on this page :
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
Now, I would like to be able to use the same kind of dependency injection but with a dynamically defined value, using a decorator.
def config_checker(value):
checker = FixedContentQueryChecker(value)
def f(func):
@functools.wraps(func)
async def wrap_func(*args, fixed_content_included: Annotated[bool, Depends(checker)], **kwargs):
return await func(*args, fixed_content_included, **kwargs)
return wrap_func
return f
@app.get("/query-bar-checker/")
@config_checker(value="bar")
async def read_query_check_bar(fixed_content_included: Annotated[bool, Depends(??)]):
return {"fixed_content_in_query": fixed_content_included}
@app.get("/query-foo-checker/")
@config_checker(value="foo")
async def read_query_check_foo(fixed_content_included: Annotated[bool, Depends(??)]):
return {"fixed_content_in_query": fixed_content_included}
The problem is I need to define the fixed_content_included
as a dependency in the routes so that it won't be treated as a query parameter.
But if I provide anything in the Depends() function in the route definition, it won't be able to be overridden by the decorator so that the parametrized function would be used.
How can I proceed ?
I started from the example shown on this page : https://fastapi.tiangolo.com/advanced/advanced-dependencies/#use-the-instance-as-a-dependency
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
Now, I would like to be able to use the same kind of dependency injection but with a dynamically defined value, using a decorator.
def config_checker(value):
checker = FixedContentQueryChecker(value)
def f(func):
@functools.wraps(func)
async def wrap_func(*args, fixed_content_included: Annotated[bool, Depends(checker)], **kwargs):
return await func(*args, fixed_content_included, **kwargs)
return wrap_func
return f
@app.get("/query-bar-checker/")
@config_checker(value="bar")
async def read_query_check_bar(fixed_content_included: Annotated[bool, Depends(??)]):
return {"fixed_content_in_query": fixed_content_included}
@app.get("/query-foo-checker/")
@config_checker(value="foo")
async def read_query_check_foo(fixed_content_included: Annotated[bool, Depends(??)]):
return {"fixed_content_in_query": fixed_content_included}
The problem is I need to define the fixed_content_included
as a dependency in the routes so that it won't be treated as a query parameter.
But if I provide anything in the Depends() function in the route definition, it won't be able to be overridden by the decorator so that the parametrized function would be used.
How can I proceed ?
Share Improve this question asked yesterday ibi0tuxibi0tux 2,6195 gold badges33 silver badges55 bronze badges 4 |1 Answer
Reset to default 0I eventually found a solution using the fastapi-decorators library.
Here's what I achieved to do so far :
import functools
from fastapi import Depends, FastAPI
from fastapi_decorators import depends
app = FastAPI()
def config_checker(value):
def f(func):
def checker():
return value
@depends(fixed_content_included=Depends(checker))
@functools.wraps(func)
async def wrap_func(*args, fixed_content_included, **kwargs):
return await func(*args, fixed_content_included=fixed_content_included, **kwargs)
return wrap_func
return f
@app.get("/")
@config_checker(value="foobar")
async def read_query_check_bar(fixed_content_included):
return {"fixed_content_in_query": fixed_content_included}
@app.get("/two")
@config_checker(value="quux")
async def read_query_check_bar(fixed_content_included):
return {"fixed_content_in_query": fixed_content_included}
I still need to check if it can still fit more complex needs but I think it answers what I was asking for here.
本文标签: pythonFastAPI dynamic advanced dependencies Stack Overflow
版权声明:本文标题:python - FastAPI dynamic advanced dependencies- Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736605586a1945318.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
fixed_content_included: Annotated[bool, Depends(FixedContentQueryChecker("bar"))]
in your function and skipping the decorator? A dependency will have no access to the function it's being used in, so I'm not sure what you're asking for is actually doable. – M.O. Commented yesterdayFixedContentQueryChecker
and it may become quite awful to read. Using a decorator seemed to be syntaxically prettier. – ibi0tux Commented yesterdayAnnotated[bool, Depends(checker)]
to a variable (ContentChecker = Annotated[bool, Depends(checker)]
), so that you writefixed_content_included: ContentChecker
in your controllers - making the controller definition succinct. Another option is to make a helper function that returns the annotation (if you want the parameterized version), and then use that:fixed_content_included: Checker("bar")
, whereChecker
is a function that returnsAnnotated[...]
with a dynamic function returned toDepends
. Decorate it w/cache to make it testable. – MatsLindh Commented yesterdayfixed_content_included: Checker("bar")
sounds good but I would like the"bar"
value to be defined in a decorator. I could use the decorator to do that, like shown in my code where i add the Annotated[..., Depends()]` in thewrap_func
definition. The only issue I'm left with is how can I make the parameter use the Annotated version defined in the decorator ? – ibi0tux Commented yesterday