.. image:: https://travis-ci.com/lmcgartland/graphene-file-upload.svg?branch=master
:target: https://travis-ci.com/lmcgartland/graphene-file-upload
.. image:: https://badge.fury.io/py/graphene-file-upload.svg
:target: https://badge.fury.io/py/graphene-file-upload
graphene-file-upload
====================
``graphene-file-upload`` is a drop in replacement for the the GraphQL
view in Graphene for Django, and for Flask-Graphql.
It supports multi-part file uploads that adhere to the `Multipart Request Spec <https://github.com/jaydenseric/graphql-multipart-request-spec>`_.
It currently supports Python 2.7 and 3.4+.
Installation:
-------------
.. code:: bash
$ pip install graphene-file-upload
Usage
-----
To add an upload type to your mutation, import and use ``Upload``.
Upload is a scalar type.
.. code:: python
from graphene_file_upload.scalars import Upload
class UploadMutation(graphene.Mutation):
class Arguments:
file = Upload(required=True)
success = graphene.Boolean()
def mutate(self, info, file, **kwargs):
# do something with your file
return UploadMutation(success=True)
Django Integration:
~~~~~~~~~~~~~~~~~~~
To use, import the view, then add to your list of urls (replace previous
GraphQL view).
.. code:: python
from graphene_file_upload.django import FileUploadGraphQLView
urlpatterns = [
url(r'^graphql', FileUploadGraphQLView.as_view(graphiql=True)),
]
Flask Integration:
~~~~~~~~~~~~~~~~~~
Note that ``flask-graphql`` version ``<2.0`` is not supported. At the
time of writing this README, you must install ``flask-graphql`` with
``pip install --pre flask-graphql``
Simply import the modified view and create a new url rule on your app:
.. code:: python
from graphene_file_upload.flask import FileUploadGraphQLView
app.add_url_rule(
'/graphql',
view_func=FileUploadGraphQLView.as_view(
...
)
)
Testing
-------
Flask
~~~~~
`<https://flask.palletsprojects.com/en/1.1.x/testing/#the-testing-skeleton/>`_
.. code:: python
# Create a fixture using the file_graphql_query helper and `client` fixture.
import os
import json
import tempfile
from flaskr import flaskr
import pytest
from graphene_file_upload.django.testing import file_graphql_query
@pytest.fixture
def client():
db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
flaskr.app.config['TESTING'] = True
with flaskr.app.test_client() as client:
with flaskr.app.app_context():
flaskr.init_db()
yield client
os.close(db_fd)
os.unlink(flaskr.app.config['DATABASE'])
@pytest.fixture
def client_query(client):
def func(*args, **kwargs):
return file_graphql_query(*args, **kwargs, client=client)
return func
# Test your query using the client_query fixture
def test_some_query(client_query):
test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))
response = client_query(
'''
mutation testMutation($file: Upload!) {
myUpload(fileIn: $file) {
ok
}
}
''',
op_name='testMutation'
files={'file': test_file},
)
content = json.loads(response.content)
assert 'errors' not in content
Django
~~~~~~
Writing test using `django's test client <https://docs.djangoproject.com/en/3.1/topics/testing/tools/#default-test-client />`_
Using pytest
############
To use pytest define a simple fixture using the query helper below
.. code:: python
# Create a fixture using the file_graphql_query helper and ``client` fixture from ``pytest-django``.
import json
import pytest
from graphene_file_upload.django.testing import file_graphql_query
@pytest.fixture
def client_query(client):
def func(*args, **kwargs):
return file_graphql_query(*args, **kwargs, client=client)
return func
# Test your query using the client_query fixture
def test_some_query(client_query):
test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))
response = client_query(
'''
mutation testMutation($file: Upload!) {
myUpload(fileIn: $file) {
ok
}
}
''',
op_name='testMutation'
files={'file': test_file},
)
content = json.loads(response.content)
assert 'errors' not in content
Using unittest
##############
Your endpoint is set through the ``GRAPHQL_URL`` attribute on ``GraphQLFileUploadTestCase``.
The default endpoint is ``GRAPHQL_URL = “/graphql/”``.
.. code:: python
import json
from graphene_file_upload.django.testing import GraphQLFileUploadTestCase
class MutationTestCase(GraphQLFileUploadTestCase):
def test_some_mutation(self):
test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))
response = self.file_query(
'''
mutation testMutation($file: Upload!) {
myUpload(fileIn: $file) {
ok
}
}
''',
op_name='testMutation',
files={'file': test_file},
)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
Contributing:
-------------
If you'd like to contribute, please run the test suite prior to sending a PR.
In order to run the testing environment, create a virtual environment, install
tox, and run the tox commands:
.. code:: bash
$ python3 -m venv venv
$ source venv/bin/activate
$ make install
# You may have to deactivate and reactivate to have access to the tox command,
# depending on your system.
# Run the test suite with the versions of python you have installed
$ tox
# Alternatively, if you're using something like pyenv and can easily install
# Multiple versions of python, then try running the following command
$ tox
# If for some reason you need to recreate the tox environment (e.g. a new
# dependency has been added since you last ran it, add the -r flag to the
# tox command)
$ tox -r {...additional flags...}
Check out `pyenv
<https://github.com/pyenv/pyenv>`_ if you'd like a simple way of
installing multiple python versions to test out.
Packaging for PyPi:
-------------------
Run
.. code:: bash
$ make deploy
Raw data
{
"_id": null,
"home_page": "https://github.com/lmcgartland/graphene-file-upload",
"name": "graphene-file-upload",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "graphql,graphene,apollo,upload",
"author": "Lucas McGartland",
"author_email": "lucasmcgartland@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/25/9a/d06f6e3fa33a53c8ba2cbe1a5ad509b7dc7124e85f221b8e13cee6c7d0c2/graphene_file_upload-1.3.0.tar.gz",
"platform": "",
"description": ".. image:: https://travis-ci.com/lmcgartland/graphene-file-upload.svg?branch=master\n :target: https://travis-ci.com/lmcgartland/graphene-file-upload\n\n.. image:: https://badge.fury.io/py/graphene-file-upload.svg\n :target: https://badge.fury.io/py/graphene-file-upload\n\n\ngraphene-file-upload\n====================\n\n``graphene-file-upload`` is a drop in replacement for the the GraphQL\nview in Graphene for Django, and for Flask-Graphql. \n\nIt supports multi-part file uploads that adhere to the `Multipart Request Spec <https://github.com/jaydenseric/graphql-multipart-request-spec>`_.\n\nIt currently supports Python 2.7 and 3.4+.\n\nInstallation:\n-------------\n\n.. code:: bash\n\n $ pip install graphene-file-upload\n\nUsage\n-----\n\nTo add an upload type to your mutation, import and use ``Upload``.\nUpload is a scalar type.\n\n.. code:: python\n\n from graphene_file_upload.scalars import Upload\n\n class UploadMutation(graphene.Mutation):\n class Arguments:\n file = Upload(required=True)\n\n success = graphene.Boolean()\n\n def mutate(self, info, file, **kwargs):\n # do something with your file\n\n return UploadMutation(success=True)\n\nDjango Integration:\n~~~~~~~~~~~~~~~~~~~\n\nTo use, import the view, then add to your list of urls (replace previous\nGraphQL view).\n\n.. code:: python\n\n from graphene_file_upload.django import FileUploadGraphQLView\n\n urlpatterns = [\n url(r'^graphql', FileUploadGraphQLView.as_view(graphiql=True)),\n ]\n\nFlask Integration:\n~~~~~~~~~~~~~~~~~~\n\nNote that ``flask-graphql`` version ``<2.0`` is not supported. At the\ntime of writing this README, you must install ``flask-graphql`` with\n``pip install --pre flask-graphql``\n\nSimply import the modified view and create a new url rule on your app:\n\n.. code:: python\n\n from graphene_file_upload.flask import FileUploadGraphQLView\n\n app.add_url_rule(\n '/graphql',\n view_func=FileUploadGraphQLView.as_view(\n ...\n )\n )\n\nTesting\n-------\n\nFlask\n~~~~~\n\n`<https://flask.palletsprojects.com/en/1.1.x/testing/#the-testing-skeleton/>`_\n\n.. code:: python\n\n # Create a fixture using the file_graphql_query helper and `client` fixture.\n import os\n import json\n import tempfile\n\n from flaskr import flaskr\n import pytest\n from graphene_file_upload.django.testing import file_graphql_query\n\n\n @pytest.fixture\n def client():\n db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()\n flaskr.app.config['TESTING'] = True\n\n with flaskr.app.test_client() as client:\n with flaskr.app.app_context():\n flaskr.init_db()\n yield client\n\n os.close(db_fd)\n os.unlink(flaskr.app.config['DATABASE'])\n\n @pytest.fixture\n def client_query(client):\n def func(*args, **kwargs):\n return file_graphql_query(*args, **kwargs, client=client)\n\n return func\n\n # Test your query using the client_query fixture\n def test_some_query(client_query):\n test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))\n\n response = client_query(\n '''\n mutation testMutation($file: Upload!) {\n myUpload(fileIn: $file) {\n ok\n }\n }\n ''',\n op_name='testMutation'\n files={'file': test_file},\n )\n\n content = json.loads(response.content)\n assert 'errors' not in content\n\n\nDjango\n~~~~~~\n\nWriting test using `django's test client <https://docs.djangoproject.com/en/3.1/topics/testing/tools/#default-test-client />`_\n\nUsing pytest\n############\n\nTo use pytest define a simple fixture using the query helper below\n\n.. code:: python\n\n # Create a fixture using the file_graphql_query helper and ``client` fixture from ``pytest-django``.\n\n import json\n import pytest\n from graphene_file_upload.django.testing import file_graphql_query\n\n @pytest.fixture\n def client_query(client):\n def func(*args, **kwargs):\n return file_graphql_query(*args, **kwargs, client=client)\n\n return func\n\n # Test your query using the client_query fixture\n def test_some_query(client_query):\n test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))\n\n response = client_query(\n '''\n mutation testMutation($file: Upload!) {\n myUpload(fileIn: $file) {\n ok\n }\n }\n ''',\n op_name='testMutation'\n files={'file': test_file},\n )\n\n content = json.loads(response.content)\n assert 'errors' not in content\n\n\nUsing unittest\n##############\n\nYour endpoint is set through the ``GRAPHQL_URL`` attribute on ``GraphQLFileUploadTestCase``. \n\nThe default endpoint is ``GRAPHQL_URL = \u201c/graphql/\u201d``.\n\n.. code:: python\n\n import json\n\n from graphene_file_upload.django.testing import GraphQLFileUploadTestCase\n\n class MutationTestCase(GraphQLFileUploadTestCase):\n def test_some_mutation(self):\n test_file = SimpleUploadedFile(name='test.txt', content=file_text.encode('utf-8'))\n\n response = self.file_query(\n '''\n mutation testMutation($file: Upload!) {\n myUpload(fileIn: $file) {\n ok\n }\n }\n ''',\n op_name='testMutation',\n files={'file': test_file},\n )\n\n # This validates the status code and if you get errors\n self.assertResponseNoErrors(response)\n\n\nContributing:\n-------------\n\nIf you'd like to contribute, please run the test suite prior to sending a PR.\n\nIn order to run the testing environment, create a virtual environment, install\ntox, and run the tox commands:\n\n.. code:: bash\n\n $ python3 -m venv venv\n $ source venv/bin/activate\n $ make install\n # You may have to deactivate and reactivate to have access to the tox command,\n # depending on your system.\n\n # Run the test suite with the versions of python you have installed\n $ tox\n # Alternatively, if you're using something like pyenv and can easily install\n # Multiple versions of python, then try running the following command\n $ tox\n\n # If for some reason you need to recreate the tox environment (e.g. a new\n # dependency has been added since you last ran it, add the -r flag to the\n # tox command)\n $ tox -r {...additional flags...}\n\nCheck out `pyenv\n<https://github.com/pyenv/pyenv>`_ if you'd like a simple way of\ninstalling multiple python versions to test out.\n\nPackaging for PyPi:\n-------------------\n\nRun\n\n.. code:: bash\n\n $ make deploy\n\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Lib for adding file upload functionality to GraphQL mutations in Graphene Django and Flask-Graphql",
"version": "1.3.0",
"project_urls": {
"Homepage": "https://github.com/lmcgartland/graphene-file-upload"
},
"split_keywords": [
"graphql",
"graphene",
"apollo",
"upload"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9ab22961fd74e960729a667137435dc3229fb38d73f447c9a6da58372344ab32",
"md5": "666a416464336d46859cdf51966c54a5",
"sha256": "5afe50f409f50e3d198fd92c883d98d868e6c6aaadf5df3a3f4d88ecad90ed97"
},
"downloads": -1,
"filename": "graphene_file_upload-1.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "666a416464336d46859cdf51966c54a5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 8941,
"upload_time": "2021-02-20T19:28:11",
"upload_time_iso_8601": "2021-02-20T19:28:11.348804Z",
"url": "https://files.pythonhosted.org/packages/9a/b2/2961fd74e960729a667137435dc3229fb38d73f447c9a6da58372344ab32/graphene_file_upload-1.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "259ad06f6e3fa33a53c8ba2cbe1a5ad509b7dc7124e85f221b8e13cee6c7d0c2",
"md5": "73e0ad8ce951ea94453ace3e57175b30",
"sha256": "6898480b0556826472c80971032917c01968ade5800d84054008fe598795b063"
},
"downloads": -1,
"filename": "graphene_file_upload-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "73e0ad8ce951ea94453ace3e57175b30",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10742,
"upload_time": "2021-02-20T19:28:13",
"upload_time_iso_8601": "2021-02-20T19:28:13.011998Z",
"url": "https://files.pythonhosted.org/packages/25/9a/d06f6e3fa33a53c8ba2cbe1a5ad509b7dc7124e85f221b8e13cee6c7d0c2/graphene_file_upload-1.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2021-02-20 19:28:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "lmcgartland",
"github_project": "graphene-file-upload",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "graphene-file-upload"
}