Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use graphene.List(Upload) to upload multiple files? #14

Open
emilt27 opened this issue Sep 7, 2018 · 5 comments
Open

Comments

@emilt27
Copy link

emilt27 commented Sep 7, 2018

The question in title ^^.
screen shot 2018-09-07 at 12 29 28 pm

@emilt27
Copy link
Author

emilt27 commented Sep 7, 2018

I've figured out why it does not work. I have the following:

class AddItem(graphene.relay.ClientIDMutation):
    class Input:
        files = graphene.List(Upload)
        expires = graphene.Date(required=True)

When I try to execute this mutation with wrong expires value, it tries to return the error with serialized payloads. Here is a line where it tries to serialize: https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/values.py#L73

@marlonpatrick
Copy link

Oops man, when solving the problem of the field "expires" the upload with multiple files is working well? I am evaluating this library. I wanted to know if it is stable considering that my application will use a lot of image uploads.

@sreerajkksd
Copy link

Do we have a solution for uploading multiple files together ?

@sreerajkksd
Copy link

sreerajkksd commented Sep 17, 2020

I spend sometime on this and this is definitely working fine. I read https://medium.com/@dilipkumar/graphql-and-file-upload-using-react-and-node-js-c1d629e1b86b to understand the payload structure and just did what they asked me to do.

In summary, we have to put the following keys and values in form-data

operations:{"query": "mutation uploadFiles($files: [Upload]) {uploadFiles(files: $files) { success }", "variables": { "files": [null,null] }}
map:{ "0": ["variables.files.0"], "1": ["variables.files.1"]}

Additionally 0 key should contain the content of the first file and 1 should contain the content of the second file.

@melvyn-apryl
Copy link

Here's how to create a test for Django, combining all the bits of information from above + some figuring out:

# test_upload.py

import random

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile

def get_bytes(size: int) -> bytes:
    return bytes(bytearray(random.getrandbits(8) for _ in range(size)))

UPLOAD_DOCUMENTS = """mutation uploadDocuments($documents: [Upload]!) {
 uploadDocuments(documents: $documents) {
  	success
	} 
}"""

def test_upload():
    # Note the keys: variablename dot index_number
    documents = {
        "documents.0": SimpleUploadedFile(
            name="scanned contract.png",
            content=get_bytes(1024),
            content_type="image/png",
        ),
        "documents.1": SimpleUploadedFile(
            name="Invoice.pdf",
            content=get_bytes(2048),
            content_type="application/pdf",
        ),
    }

    response = file_graphql_query(
        UPLOAD_DOCUMENTS, files=documents, variables={"documents": [None, None]}
    )
    assert response.json()["data"]["uploadDocuments"]["success"] is True

# schema.py

class uploadDocuments(graphene.Mutation):
    success = graphene.Boolean()
    class Arguments:
        documents = graphene.NonNull(graphene.List(Upload))

    @classmethod
    def mutate(
        cls,
        root,
        info: td.ResolveInfo,
        documents: t.List[SimpleUploadedFile],
    ):
        if isinstance(documents[0], SimpleUploadedFile) and isinstance(
            documents[1], SimpleUploadedFile
        ):
            return cls(success=True)

        return cls(success=False)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants