使用functools.用稍微不同的参数列表包装函数



我想这样做:

def need_session(func):
@wraps(func)
def wrapper(*args, **kwargs):
session = SessionLocal()
try:
func(session, *args, **kwargs)
finally:
session.close()

我使用的是wraps函数,因为我使用的是Strawberry,它取决于参数类型。

如您所见,func有一个额外的session参数。

我怎样才能使它工作?

如果我尝试使用Strawberry运行GraphQL服务器,其中的函数使用上面的装饰器进行装饰,它会给我这个错误:

TypeError: Mutation fields cannot resolved。异常类型''

如果我把装饰符改成这样:

def need_session(func):
@wraps(func)
def wrapper(*args, **kwargs):
session = SessionLocal()
kwargs['session'] = session
try:
func(*args, **kwargs)
finally:
session.close()

并将修饰函数的参数列表更改为:

def some_func(some_arg: SomeClass, **kwargs):
...

我仍然得到这个错误:

strawberry.exceptions。MissingArgumentsAnnotationsError:缺少参数的注释在"login_user"字段中,您是否忘记添加它?

为什么出现错误?

你得到这个异常,因为草莓不支持**kwargs和每个strawberry.field必须有注解的所有参数。它们是由strawberry.type修饰器处理的,所以你不能修改函数签名。

可能解决方案1:

您可以通过编写模式扩展在StrawberryInfo中提供会话。

的例子:

from strawberry.extensions import Extension
from mydb import get_db_session

class DbSessionMiddleWare(Extension):
def on_request_start(self):
self.execution_context.context["db"] = get_db_session()
def on_request_end(self):
self.execution_context.context["db"].close()
schema = strawberry.Schema(
query=Queries,
mutation=Mutations,
extensions=[
DbSessionMiddleWare,
],
)

一些解析器:

from strawberry.types import Info

def resolve_name(info: Info):
name = info.context['db'].execute("SELECT ...")

可能解决方案2:

你可以用你自己的装饰器包装Strawberry装饰器,并按你的意愿注入一些注释。
请记住,您应该从函数签名中清除任何*args**kwargs,否则strawberry会抱怨这一点。

的例子:

from strawberry.arguments import StrawberryArgument, StrawberryAnnotation, UNSET
import inspect
def create_strawberry_argument(
python_name: str, graphql_name: str, type_, default=None
):
return StrawberryArgument(
python_name=python_name,
graphql_name=graphql_name,
type_annotation=StrawberryAnnotation(type_),
default=default or UNSET,
)
def hide_args_kwargs(field):
sig = inspect.signature(field)
cleared = tuple(
p for p in sig.parameters.values() if p.name not in ("kwargs", "args")
)
field.__signature__ = inspect.signature(field).replace(parameters=(cleared))
return field
def inject_mutation(field, arguments: tuple[str, type]):
field = hide_args_kwargs(field)
field = strawberry.mutation(field, description=field.__doc__)
for arg_tuple in arguments:
arg = create_strawberry_argument(arg_tuple[0], arg_tuple[0], arg_tuple[1])
field.arguments.append(arg)
return field
@inject_mutation(('arg2', int))
def some_resolver(info, arg1, **kwargs) -> SomeOutputType:
f = kwargs.get('arg2', None)

相关内容

  • 没有找到相关文章