使用 GraphQL +Ariadne + Flask 上传文件:graphql.error.graphql_error.GraphQLError: Operation data should be

Posted

技术标签:

【中文标题】使用 GraphQL +Ariadne + Flask 上传文件:graphql.error.graphql_error.GraphQLError: Operation data should be an JSON object【英文标题】:Upload file with GraphQL +Ariadne + Flask: graphql.error.graphql_error.GraphQLError: Operation data should be a JSON object 【发布时间】:2021-09-10 00:13:55 【问题描述】:

我正在尝试使用此技术堆栈(Flask + Graphql + Ariadne)上传文件。我已经实现了其他 API,但现在对于文件上传,它返回了这个错误。

错误

Traceback (most recent call last):
  File "d:\project\python-envs\graph_ql_env\lib\site-packages\ariadne\graphql.py", line 138, in graphql_sync
    validate_data(data)
  File "d:\project\python-envs\graph_ql_env\lib\site-packages\ariadne\graphql.py", line 354, in validate_data
    raise GraphQLError("Operation data should be a JSON object")
graphql.error.graphql_error.GraphQLError: Operation data should be a JSON object
127.0.0.1 - - [Time] "POST /graphql HTTP/1.1" 400 -

项目文件。

schema.graphql

scalar Upload

type Mutation 
    uploadProfileImage(id: String!, image: Upload!): Boolean!

mutation.py

@convert_kwargs_to_snake_case
def resolve_upload_profile_image(obj, info, id, file):

ma​​in.py

mutation.set_field("uploadProfileImage", M.resolve_upload_profile_image)

type_defs = load_schema_from_path("schema.graphql")
schema = make_executable_schema(
    type_defs, query, mutation, upload_scalar, snake_case_fallback_resolvers
)

@app.route("/graphql", methods=["POST"])
def graphql_server():
    data = request.get_json()

    success, result = graphql_sync(
        schema,
        data,
        context_value=request,
        debug=app.debug
    )

    status_code = 200 if success else 400
    return jsonify(result), status_code

使用 Altair 查询

mutation ($image: Upload!) 
  uploadProfileImage (id:"qwe1", image:$image)

【问题讨论】:

【参考方案1】:

在这里找到了解决方案: https://spectrum.chat/ariadne/general/does-anyone-have-a-working-example-of-file-uploads-in-ariadne~e5fee18b-6e41-4669-b723-6526cd1c549d

@graphql_bp.route("/", methods=["POST"])
def graphql_server():
    if request.content_type.startswith("multipart/form-data"):
        data = combine_multipart_data(
            json.loads(request.form.get("operations")),
            json.loads(request.form.get("map")),
            dict(request.files)
        )
    else:
        data = request.get_json()
    success, result = graphql_sync(
        schema,
        data,
        context_value=request,
        debug=current_app.debug
    )
    status_code = 200 if success else 400
    return jsonify(result), status_code

【讨论】:

以上是关于使用 GraphQL +Ariadne + Flask 上传文件:graphql.error.graphql_error.GraphQLError: Operation data should be 的主要内容,如果未能解决你的问题,请参考以下文章

Ariadne GraphQL 文档中缺少信息

Graphql 突变以上传具有其他字段的文件

无法在 python graphql 框架中启用 CORS/允许标头 - ariadne

没有外部服务器的 Python GraphQL Ariadne WSGI 示例

在解析器之前修改 Ariadne 中的上下文

Ariadne 中联合类型的解析器函数