Skip to content

Commit

Permalink
Improve project quality check
Browse files Browse the repository at this point in the history
Project:
- Removed support for python<3.6 from classifier
- Added poetry package management
- Added dev dependencies in poetry
- Added black, coverage, travis badges to README

Testing:
- Removed testing project and added tests folder
- Tests are now using pytest with the appropriate configuration
- Added tox for testings purposes
- Added quality checks
- Added coverage

Quality:
- Added linters
- Blacked project
  • Loading branch information
Ouradze committed Feb 1, 2019
1 parent 2168d3d commit 524ace6
Show file tree
Hide file tree
Showing 57 changed files with 2,509 additions and 1,428 deletions.
7 changes: 7 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Keep in sync with setup.cfg which is used for source packages.

[flake8]
ignore = E203, E266, E501, W503
max-line-length = 80
max-complexity = 18
select = B,C,E,F,W,T4,B9
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ __pycache__

# testing files
*db.sqlite3

# Specific Files & Folders
.coverage*
.tox/
.pytest*/

40 changes: 40 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
language: python
dist: xenial

stages:
- quality
- test

cache:
pip: true
directories:
- $HOME/.cache/pypoetry

matrix:
fast_finish: true
include:
- { python: "3.6", env: DJANGO=2.0 }
- { python: "3.6", env: DJANGO=2.1 }

- { python: "3.7", env: DJANGO=2.0 }
- { python: "3.7", env: DJANGO=2.1 }

- { python: "3.6", env: TOXENV=quality }

before_install:
- pip install codecov

install:
- pip install pip -U
- pip install tox-travis
- curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
- source $HOME/.poetry/env
script:
- tox

after_success:
- pip install codecov
- codecov -e TOXENV,DJANGO

notifications:
email: false
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@

---

# Graphene-Django-Extras [![PyPI version](https://badge.fury.io/py/graphene-django-extras.svg)](https://badge.fury.io/py/graphene-django-extras)

# Graphene-Django-Extras
[![build-status-image]][travis]
[![coverage-status-image]][codecov]
[![pypi-version]][pypi]
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)


[build-status-image]: https://secure.travis-ci.org/encode/graphene-django-extras.svg?branch=master
[travis]: https://travis-ci.org/eamigo86/graphene-django-extras?branch=master
[coverage-status-image]: https://img.shields.io/codecov/c/gh/encode/graphene-django-extras/master.svg
[codecov]: https://codecov.io/gh/eamigo86/graphene-django-extras?branch=master
[pypi-version]: https://img.shields.io/pypi/v/graphene_django_extras.svg
[pypi]: https://pypi.org/project/graphene_django_extras/

This package add some extra functionalities to graphene-django to facilitate the graphql use without Relay:
1. Allows pagination and filtering on Queries.
Expand Down
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Graphene-Django-Extras
======================

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black

This package add some extra functionalities to **graphene-django** to facilitate the graphql use without Relay:
1. Allows pagination and filtering on Queries.
2. Allows to define DjangoRestFramework serializers based Mutations.
Expand Down
52 changes: 28 additions & 24 deletions graphene_django_extras/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,45 @@
from graphene.pyutils.version import get_version

from .directives import all_directives
from .fields import DjangoObjectField, DjangoFilterListField, DjangoFilterPaginateListField, \
DjangoListObjectField
from .fields import (
DjangoObjectField,
DjangoFilterListField,
DjangoFilterPaginateListField,
DjangoListObjectField,
)
from .middleware import ExtraGraphQLDirectiveMiddleware
from .mutation import DjangoSerializerMutation
from .paginations import LimitOffsetGraphqlPagination, PageGraphqlPagination, CursorGraphqlPagination
from .types import DjangoObjectType, DjangoInputObjectType, DjangoListObjectType, DjangoSerializerType
from .paginations import LimitOffsetGraphqlPagination, PageGraphqlPagination
from .types import (
DjangoObjectType,
DjangoInputObjectType,
DjangoListObjectType,
DjangoSerializerType,
)

VERSION = (0, 4, 3, 'final', '')
VERSION = (0, 4, 3, "final", "")

__version__ = get_version(VERSION)

__all__ = (
'__version__',

"__version__",
# FIELDS
'DjangoObjectField',
'DjangoFilterListField',
'DjangoFilterPaginateListField',
'DjangoListObjectField',

"DjangoObjectField",
"DjangoFilterListField",
"DjangoFilterPaginateListField",
"DjangoListObjectField",
# MUTATIONS
'DjangoSerializerMutation',

"DjangoSerializerMutation",
# PAGINATIONS
'LimitOffsetGraphqlPagination',
'PageGraphqlPagination',
"LimitOffsetGraphqlPagination",
"PageGraphqlPagination",
# 'CursorGraphqlPagination', # Not implemented yet

# TYPES
'DjangoObjectType',
'DjangoListObjectType',
'DjangoInputObjectType',
'DjangoSerializerType',

"DjangoObjectType",
"DjangoListObjectType",
"DjangoInputObjectType",
"DjangoSerializerType",
# DIRECTIVES
'all_directives',
'ExtraGraphQLDirectiveMiddleware'
"all_directives",
"ExtraGraphQLDirectiveMiddleware",
)
102 changes: 53 additions & 49 deletions graphene_django_extras/base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,62 +12,66 @@

def factory_type(operation, _type, *args, **kwargs):

if operation == 'output':
if operation == "output":

class GenericType(_type):
class Meta:
model = kwargs.get('model')
name = kwargs.get('name') or to_camel_case('{}_Generic_Type'.format(
kwargs.get('model') .__name__)
model = kwargs.get("model")
name = kwargs.get("name") or to_camel_case(
"{}_Generic_Type".format(kwargs.get("model").__name__)
)
only_fields = kwargs.get('only_fields')
exclude_fields = kwargs.get('exclude_fields')
include_fields = kwargs.get('include_fields')
filter_fields = kwargs.get('filter_fields')
filterset_class = kwargs.get('filterset_class')
registry = kwargs.get('registry')
skip_registry = kwargs.get('skip_registry')
only_fields = kwargs.get("only_fields")
exclude_fields = kwargs.get("exclude_fields")
include_fields = kwargs.get("include_fields")
filter_fields = kwargs.get("filter_fields")
filterset_class = kwargs.get("filterset_class")
registry = kwargs.get("registry")
skip_registry = kwargs.get("skip_registry")
# fields = kwargs.get('fields')
description = 'Auto generated Type for {} model'.format(
kwargs.get('model').__name__
description = "Auto generated Type for {} model".format(
kwargs.get("model").__name__
)

return GenericType

elif operation == 'input':
elif operation == "input":

class GenericInputType(_type):
class Meta:
model = kwargs.get('model')
name = kwargs.get('name') or to_camel_case('{}_{}_Generic_Type'.format(
kwargs.get('model').__name__, args[0]))
only_fields = kwargs.get('only_fields')
exclude_fields = kwargs.get('exclude_fields')
nested_fields = kwargs.get('nested_fields')
registry = kwargs.get('registry')
skip_registry = kwargs.get('skip_registry')
model = kwargs.get("model")
name = kwargs.get("name") or to_camel_case(
"{}_{}_Generic_Type".format(kwargs.get("model").__name__, args[0])
)
only_fields = kwargs.get("only_fields")
exclude_fields = kwargs.get("exclude_fields")
nested_fields = kwargs.get("nested_fields")
registry = kwargs.get("registry")
skip_registry = kwargs.get("skip_registry")
input_for = args[0]
description = 'Auto generated InputType for {} model'.format(
kwargs.get('model').__name__
description = "Auto generated InputType for {} model".format(
kwargs.get("model").__name__
)

return GenericInputType

elif operation == 'list':
elif operation == "list":

class GenericListType(_type):
class Meta:
model = kwargs.get('model')
name = kwargs.get('name') or to_camel_case('{}_List_Type'.format(
kwargs.get('model').__name__
))
only_fields = kwargs.get('only_fields')
exclude_fields = kwargs.get('exclude_fields')
filter_fields = kwargs.get('filter_fields')
filterset_class = kwargs.get('filterset_class')
results_field_name = kwargs.get('results_field_name')
pagination = kwargs.get('pagination')
queryset = kwargs.get('queryset')
registry = kwargs.get('registry')
description = 'Auto generated list Type for {} model'.format(
kwargs.get('model').__name__
model = kwargs.get("model")
name = kwargs.get("name") or to_camel_case(
"{}_List_Type".format(kwargs.get("model").__name__)
)
only_fields = kwargs.get("only_fields")
exclude_fields = kwargs.get("exclude_fields")
filter_fields = kwargs.get("filter_fields")
filterset_class = kwargs.get("filterset_class")
results_field_name = kwargs.get("results_field_name")
pagination = kwargs.get("pagination")
queryset = kwargs.get("queryset")
registry = kwargs.get("registry")
description = "Auto generated list Type for {} model".format(
kwargs.get("model").__name__
)

return GenericListType
Expand All @@ -76,24 +80,24 @@ class Meta:


class DjangoListObjectBase(object):
def __init__(self, results, count, results_field_name='results'):
def __init__(self, results, count, results_field_name="results"):
self.results = results
self.count = count
self.results_field_name = results_field_name

def to_dict(self):
return {
self.results_field_name: [e.to_dict() for e in self.results],
'count': self.count,
"count": self.count,
}


def resolver(attr_name, root, instance, info):
if attr_name == 'app_label':
if attr_name == "app_label":
return instance._meta.app_label
elif attr_name == 'id':
elif attr_name == "id":
return instance.id
elif attr_name == 'model_name':
elif attr_name == "model_name":
return instance._meta.model.__name__


Expand All @@ -103,7 +107,7 @@ class GenericForeignKeyType(graphene.ObjectType):
model_name = graphene.String()

class Meta:
description = ' Auto generated Type for a model\'s GenericForeignKey field '
description = " Auto generated Type for a model's GenericForeignKey field "
default_resolver = resolver


Expand All @@ -113,7 +117,7 @@ class GenericForeignKeyInputType(graphene.InputObjectType):
model_name = graphene.Argument(graphene.String, required=True)

class Meta:
description = ' Auto generated InputType for a model\'s GenericForeignKey field '
description = " Auto generated InputType for a model's GenericForeignKey field "


# ************************************************ #
Expand Down Expand Up @@ -153,7 +157,7 @@ def serialize(time):

assert isinstance(
time, datetime.time
), ('Received not compatible time "{}"'.format(repr(time)))
), 'Received not compatible time "{}"'.format(repr(time))
return time.isoformat()


Expand All @@ -167,7 +171,7 @@ def serialize(date):
date = date.date()
assert isinstance(
date, datetime.date
), ('Received not compatible date "{}"'.format(repr(date)))
), 'Received not compatible date "{}"'.format(repr(date))
return date.isoformat()


Expand All @@ -179,5 +183,5 @@ def serialize(dt):

assert isinstance(
dt, (datetime.datetime, datetime.date)
), ('Received not compatible datetime "{}"'.format(repr(dt)))
), 'Received not compatible datetime "{}"'.format(repr(dt))
return dt.isoformat()
Loading

0 comments on commit 524ace6

Please sign in to comment.