Toolbox for changes to streamline graphene-django.
Project description
graphene-django-ai
Toolbox for changes to streamline graphene-django
ATTENTION: This package is deprecated. All functionality will live on in the ai-django-core package. Please install it with the graphql-extension enabled. More details in the changelog.
Installation
For installing graphene, just run this command in your shell
pip install "graphene-django-ai>=1.0.0"
Setup
Refer to the documentation of django-graphene
base package.
https://github.com/graphql-python/graphene-django/blob/master/README.md
Examples
GraphQL based on django ModelForms
Here is a simple Django model in my_app/models.py
:
from django.db import models
class User(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
Now we create a ModelForm
in my_app/forms.py
:
from django import forms
from .models import User
class SpaceForm(forms.ModelForm):
class Meta:
model = User
exclude = []
We need to create an ObjectType
which we derive from our model.
Lives in my_apps/schemes/schematypes.py
:
from graphene_django import DjangoObjectType
from ..models import User
class UserType(DjangoObjectType):
class Meta:
model = User
Here's the mutation in my_app/schema/mutations.py
.
It takes a ModelForm
(or a non-model form) to derive the validation rules from:
import graphene
from graphene_django_ai.forms.mutations import LoginRequiredDjangoModelFormMutation
from .schematypes import UserType
from ..forms import UserForm
class UserCreateUpdateMutation(LoginRequiredDjangoModelFormMutation):
space = graphene.Field(UserType)
class Meta:
form_class = UserForm
# Register new mutation
class UserMutation(graphene.ObjectType):
spaces = UserCreateUpdateMutation.Field(description='Create and update users')
If you register now your UserMutation
in your schema you have a working model-based and DRY API
endpoint. Congratulations!
DeleteMutation for django-model objects
If you want to delete an object you can easily use the DeleteMutation
like this:
from graphene_django_ai.schemes.mutations import DeleteMutation
from my_app.models import MyModel
class MyModelDeleteMutation(DeleteMutation):
class Meta:
model = MyModel
If you are using django-graphql-jwt
authentication you can ensure only logged in access to your delete endpoint like this:
from graphene_django_ai.schemes.mutations import LoginRequiredDeleteMutation
from my_app.models import MyModel
class MyModelDeleteMutation(LoginRequiredDeleteMutation):
class Meta:
model = MyModel
If you need to customize the validation or the base queryset you can override methods like this:
from graphene_django_ai.schemes.mutations import LoginRequiredDeleteMutation
from graphql import GraphQLError
from my_app.models import MyModel
class MyModelDeleteMutation(LoginRequiredDeleteMutation):
class Meta:
model = MyModel
def validate(self, request):
if not request.user.is_superuser:
raise GraphQLError("This is only allowed for superusers!")
def get_queryset(self, request):
return self.model.objects.filter(created_by=request.user)
JWT secure mutations
If you derive your mutation from LoginRequiredDjangoModelFormMutation
you don't have to manually take
care about securing the login with the decorators.
from graphene_django_ai.forms.mutations import LoginRequiredDjangoModelFormMutation
class MyMutation(LoginRequiredDjangoModelFormMutation):
...
Testing GraphQL calls
If you want to unittest your API calls derive your test case from the class GraphQLTestCase
.
Usage:
import json
from graphene_django.tests.base_test import GraphQLTestCase
from my_project.config.schema import schema
class MyFancyTestCase(GraphQLTestCase):
# Here you need to inject your test case's schema
GRAPHQL_SCHEMA = schema
def test_some_query(self):
response = self.query(
'''
query {
myModel {
id
name
}
}
''',
op_name='myModel'
)
content = json.loads(response.content)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
# Add some more asserts if you like
...
def test_some_mutation(self):
response = self.query(
'''
mutation myMutation($input: MyMutationInput!) {
myMutation(input: $input) {
my-model {
id
name
}
}
}
''',
op_name='myMutation',
input_data={'my_field': 'foo', 'other_field': 'bar'}
)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
# Add some more asserts if you like
...
def test_failing_call(self):
response = self.query(
'''
mutation myMutation($input: MyMutationInput!) {
myMutation(input: $badInput) {
my-model {
id
name
}
}
}
''',
op_name='myMutation',
input_data={'my_field': 'foo', 'other_field': 'bar'}
)
# This assert tests if the call raised some errors
# For example if you want to test if invalid input is handled correctly by your endpoint
self.assertResponseHasErrors(response)
# Add some more asserts if you like
...
Run tests locally
Still W.I.P.!
python -m unittest discover -v
Release a new version
-
Update
Changelog
inReadme.md
-
Create pull request / merge to master
-
Run:
- Make sure you have all the required packages installed
pip install twine wheel
- Create a file in your home directory:
~/.pypirc
[distutils] index-servers= pypi testpypi [pypi] repository: https://upload.pypi.org/legacy/ username: ambient-innovation [testpypi] repository: https://test.pypi.org/legacy/ username: ambient-innovation
- Create distribution
python setup.py sdist bdist_wheel
- Upload to Test-PyPi
twine upload --repository testpypi dist/*
- Check at Test-PyPi if it looks nice
- Upload to real PyPi
twine upload dist/*
- Make sure you have all the required packages installed
Changelog
-
1.0.8 (2020-11-18)
- Added deprection warning to main init file
-
1.0.7 (2020-11-10)
- Deprecated package and moved most code to ai-django-core
-
1.0.6 (2020-08-06)
- Removed monkey-patched bugfixes from one year ago - hopefully these issues have been resolved by now
-
1.0.5 (2020-08-06)
- Extended compat with
graphene-django
- Extended compat with
-
1.0.4 (2019-04-05)
- Fixed a bug that a BooleanField from a django form would always be required
-
1.0.3 (2019-04-05)
- Added delete mutation for django-model objects
DeleteMutation
- Added delete mutation which ensures JWT authentication
- Added delete mutation for django-model objects
-
1.0.2 (2019-04-05)
- Updated deployment documentation
- Added markdown support to Readme file
-
1.0.1 (2019-04-05)
- Added documentation about
GraphQLTestCase
- Put version to variable in
__init__.py
- Added documentation about
-
1.0.0 (2019-04-04)
- Initial package released
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file graphene-django-ai-1.0.8.tar.gz
.
File metadata
- Download URL: graphene-django-ai-1.0.8.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.38.0 CPython/3.7.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6b0f268330637852832f5f0d09eed240003eb372a1b66e1651e35f019757ca6b |
|
MD5 | e06d00fa3658f5307f08a6b13e4c8952 |
|
BLAKE2b-256 | cb0e96ba9baf865081549244c4d510b556e45ae4963e6d545bf22e08f58300ed |
File details
Details for the file graphene_django_ai-1.0.8-py3-none-any.whl
.
File metadata
- Download URL: graphene_django_ai-1.0.8-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.38.0 CPython/3.7.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 520d40f10bd07027dfaff13982363740ec1b5c8b22639df417f71d4984b08d9b |
|
MD5 | 5d9a9ddb687dfbad508c8387e0085ea9 |
|
BLAKE2b-256 | 90e4dddab27090de7d7db1da0fd587c56613ce29b1b4d625fefc5e8153eb78dd |