Graphql 柠檬黄+;FastApi认证

Graphql 柠檬黄+;FastApi认证,graphql,fastapi,Graphql,Fastapi,我正在使用Tartiflete asgi构建一个带有FastApi的Tartiflete应用程序,但我找不到一种方法来实现常规的FastApi验证或依赖注入 问题在于Tartiflete应用程序是如何构建和安装的。当做 app = FastApi() gql_app = TartifletteApp(..) app.mount("/graphql", gql_app) 我无法指定依赖项来执行标头验证。我尝试过使用FastApiinclude_router,但它根本不适用于

我正在使用Tartiflete asgi构建一个带有FastApi的Tartiflete应用程序,但我找不到一种方法来实现常规的FastApi验证或依赖注入

问题在于Tartiflete应用程序是如何构建和安装的。当做

app = FastApi()

gql_app = TartifletteApp(..)
app.mount("/graphql", gql_app)
我无法指定依赖项来执行标头验证。我尝试过使用FastApi
include_router
,但它根本不适用于TartifleteApp。我还尝试了一个小黑客,比如

gql_app = TartifletteApp(..)

app.include_router(
    gql_app.router,
    prefix="/graphql",
    # dependencies=[Depends(get_current_user)],   # here I would add a token and get a user
)
我得到了错误

File "/usr/local/lib/python3.6/site-packages/uvicorn/protocols/http/h11_impl.py", line 389, in run_asgi
     result = await app(self.scope, self.receive, self.send)
   File "/usr/local/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
     return await self.app(scope, receive, send)
   File "/usr/local/lib/python3.6/site-packages/fastapi/applications.py", line 181, in __call__
     await super().__call__(scope, receive, send)  # pragma: no cover
   File "/usr/local/lib/python3.6/site-packages/starlette/applications.py", line 111, in __call__
     await self.middleware_stack(scope, receive, send)
   File "/usr/local/lib/python3.6/site-packages/starlette/middleware/errors.py", line 181, in __call__
     raise exc from None
   File "/usr/local/lib/python3.6/site-packages/starlette/middleware/errors.py", line 159, in __call__
     await self.app(scope, receive, _send)
   File "/usr/local/lib/python3.6/site-packages/starlette/exceptions.py", line 82, in __call__
     raise exc from None
   File "/usr/local/lib/python3.6/site-packages/starlette/exceptions.py", line 71, in __call__
     await self.app(scope, receive, sender)
   File "/usr/local/lib/python3.6/site-packages/starlette/routing.py", line 566, in __call__
     await route.handle(scope, receive, send)
   File "/usr/local/lib/python3.6/site-packages/starlette/routing.py", line 227, in handle
     await self.app(scope, receive, send)
   File "/usr/local/lib/python3.6/site-packages/tartiflette_asgi/_endpoints.py", line 84, in dispatch
     graphiql = get_graphql_config(request).graphiql
   File "/usr/local/lib/python3.6/site-packages/tartiflette_asgi/_middleware.py", line 18, in get_graphql_config
     config = conn["graphql"]
   File "/usr/local/lib/python3.6/site-packages/starlette/requests.py", line 68, in __getitem__
     return self.scope[key]
 KeyError: 'graphql'
我可以将头部验证作为graphql中间件来实现,但我希望可以在Fastapi级别上实现,这样它就可以应用于每个端点


有关如何解决此问题的任何建议?

首先创建基本身份验证,然后将其添加到依赖项中,而不是获取当前用户。这将向端点添加基本身份验证

from fastapi.security import HTTPBasic, HTTPBasicCredentials

security = HTTPBasic()

app.include_router(
gql_app.router,
prefix="/graphql",
dependencies=[Depends(security)], 
)

我已经成功地解决了这个问题,没有鞑靼叶。解决方案已发布

它看起来像:

导入操作系统
导入json
导入键入
从starlette.background导入背景任务
从starlette.datastructures导入查询参数
从starlette.requests导入请求
从starlette.responses导入HTMLResponse、JSONResponse、PlainTextResponse、Response
来自Tartiflete进口引擎
类GraphQLApp:
def uuu init uuuuu(self、app、modules、schema_path=None、error_converter=None):
self.engine=发动机(
sdl=schema\u path或os.path.join(os.path.dirname(\u文件\u),“schema”),
模块=模块,
error\u-converter=error\u-converter,
)
应用程序启动事件(“启动”)(self.\u cook)
异步定义(自):
等待self.engine.cook()
定义构建上下文(自身,**kwargs):
返回kwargs或{}#在需要时在此处添加自定义逻辑
异步定义获取响应(self,请求:请求,数据:QueryParams,context:dict)->响应:
尝试:
查询=数据[“查询”]
除KeyError外:
返回PlainTextResponse(“请求中未找到GraphQL查询”,400)
定义格式错误(错误:键入.Any)->dict:
导入ast
尝试:
返回ast.literal_eval(str(error))
除值错误外:
返回{“消息”:“内部服务器错误”}
背景=背景任务()
context={“req”:请求,“background”:background,**self.\u build\u context(**context)}
结果:dict=等待self.engine.execute(
查询
上下文=上下文,
变量=data.get(“变量”),
operation_name=data.get(“operationName”),
)
内容={“数据”:结果[“数据”]}
结果中有\u errors=“errors”
如果有错误:
内容[“错误”]=“结果中错误[“错误”]的格式错误(错误)]
状态=400,如果有错误,否则为200
返回JSONResponse(内容=内容,状态\代码=状态,背景=背景)
异步def进程_请求(self,请求:请求,上下文:dict=None)->响应:
content\u type=request.headers.get(“content-type”,“”)
如果内容类型为“application/json”:
尝试:
data=wait request.json()
除了json.JSONDecodeError:
返回JSONResponse({“error”:“无效的JSON.”},400)
内容类型中的elif“应用程序/图形QL”:
body=等待请求。body()
数据={“查询”:body.decode()}
elif request.query_参数中的“query”:
data=request.query\u参数
其他:
返回明文响应(“不支持的媒体类型”,415)
return wait self.\u get\u response(请求、数据=数据、上下文=上下文或{})
所以我能做的就是

app=FastApi()
gql_app=GraphQLApp(app)
@app.post(“/graphql”)
异步def graphql_ninja(请求:请求):
返回等待gql应用程序处理请求(请求)

问题是这种方法不起作用。我在路由层遇到一些错误。我猜TartifleteApp不应该这样使用