Skip to content

Commit

Permalink
expose livehtml autobuild in Makefile + Add API autodoc (#971)
Browse files Browse the repository at this point in the history
* expose livehtml autobuild in Makefile

* add API documentation for schema

* document graphene core API

* fixes black lint

* Update graphene/types/union.py

Co-Authored-By: Jonathan Kim <jkimbo@gmail.com>

* Update graphene/types/argument.py

Co-Authored-By: Jonathan Kim <jkimbo@gmail.com>

* Update graphene/types/field.py

Co-Authored-By: Jonathan Kim <jkimbo@gmail.com>

* Update graphene/types/inputfield.py

Co-Authored-By: Jonathan Kim <jkimbo@gmail.com>

* add note about non-functional `interfaces` meta argument in mutation

* update with other virtual environment configuration

* pin autobuild

* format argument example code

* format enum input object and interface examples

* format enum mutation union examples

* revise documentation with imports, capitalization
  • Loading branch information
dvndrsn authored and jkimbo committed Jun 9, 2019
1 parent 40229b8 commit da1359e
Show file tree
Hide file tree
Showing 23 changed files with 580 additions and 26 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ __pycache__/
# Distribution / packaging
.Python
env/
venv/
.venv/
build/
develop-eggs/
dist/
Expand Down
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@ help:
@echo "Please use \`make <target>' where <target> is one of"
@grep -E '^\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "(: |##)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'

.PHONY: install-dev ## Install development dependencies
install-dev:
pip install -e ".[test]"

test:
py.test graphene

.PHONY: docs ## Generate docs
docs:
@cd docs &&\
pip install -r requirements.txt &&\
make html &&\
cd -
docs: install-dev
cd docs && make install && make html

.PHONY: docs-live ## Generate docs with live reloading
docs-live: install-dev
cd docs && make install && make livehtml
10 changes: 7 additions & 3 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ help:
@echo "Please use \`make <target>' where <target> is one of"
@grep -E '^\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "(: |##)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'

.PHONY: clean
.PHONY: install ## to install all documentation related requirements
install:
pip install -r requirements.txt

.PHONY: clean ## to remove all built documentation
clean:
rm -rf $(BUILDDIR)/*

Expand Down Expand Up @@ -199,6 +203,6 @@ dummy:
@echo
@echo "Build finished. Dummy builder generates no files."

.PHONY: livehtml
.PHONY: livehtml ## to build and serve live-reloading documentation
livehtml:
sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
sphinx-autobuild -b html --watch ../graphene $(ALLSPHINXOPTS) $(BUILDDIR)/html
Empty file added docs/_static/.gitkeep
Empty file.
106 changes: 106 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
API Reference
=============

Schema
------

.. autoclass:: graphene.types.schema.Schema
:members:

.. Uncomment sections / types as API documentation is fleshed out
.. in each class
Object types
------------

.. autoclass:: graphene.ObjectType

.. autoclass:: graphene.InputObjectType

.. autoclass:: graphene.Mutation
:members:

Fields (Mounted Types)
----------------------

.. autoclass:: graphene.Field

.. autoclass:: graphene.Argument

.. autoclass:: graphene.InputField

Fields (Unmounted Types)
------------------------

.. autoclass:: graphene.types.unmountedtype.UnmountedType

GraphQL Scalars
---------------

.. autoclass:: graphene.Int()

.. autoclass:: graphene.Float()

.. autoclass:: graphene.String()

.. autoclass:: graphene.Boolean()

.. autoclass:: graphene.ID()

Graphene Scalars
----------------

.. autoclass:: graphene.Date()

.. autoclass:: graphene.DateTime()

.. autoclass:: graphene.Time()

.. autoclass:: graphene.Decimal()

.. autoclass:: graphene.UUID()

.. autoclass:: graphene.JSONString()

Enum
----

.. autoclass:: graphene.Enum()

Structures
----------

.. autoclass:: graphene.List

.. autoclass:: graphene.NonNull

Type Extension
--------------

.. autoclass:: graphene.Interface()

.. autoclass:: graphene.Union()

Execution Metadata
------------------

.. autoclass:: graphene.ResolveInfo

.. autoclass:: graphene.Context

.. autoclass:: graphql.execution.base.ExecutionResult

.. Relay
.. -----
.. .. autoclass:: graphene.Node
.. .. autoclass:: graphene.GlobalID
.. .. autoclass:: graphene.ClientIDMutation
.. .. autoclass:: graphene.Connection
.. .. autoclass:: graphene.ConnectionField
.. .. autoclass:: graphene.PageInfo
8 changes: 5 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
import sys

sys.path.insert(0, os.path.abspath(".."))

# -- General configuration ------------------------------------------------

Expand All @@ -41,6 +42,7 @@
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
]
if not on_rtd:
extensions += ["sphinx.ext.githubpages"]
Expand Down
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ Contents:
execution/index
relay/index
testing/index
api/index

Integrations
-----
------------

* `Graphene-Django <http://docs.graphene-python.org/projects/django/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-django/>`_)
* `Graphene-SQLAlchemy <http://docs.graphene-python.org/projects/sqlalchemy/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-sqlalchemy/>`_)
Expand Down
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Required library
Sphinx==1.5.3
sphinx-autobuild==0.7.1
# Docs template
http://graphene-python.org/sphinx_graphene_theme.zip
31 changes: 31 additions & 0 deletions graphene/types/argument.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,37 @@


class Argument(MountedType):
"""
Makes an Argument available on a Field in the GraphQL schema.
Arguments will be parsed and provided to resolver methods for fields as keyword arguments.
All ``arg`` and ``**extra_args`` for a ``graphene.Field`` are implicitly mounted as Argument
using the below parameters.
.. code:: python
from graphene import String, Boolean, Argument
age = String(
# Boolean implicitly mounted as Argument
dog_years=Boolean(description="convert to dog years"),
# Boolean explicitly mounted as Argument
decades=Argument(Boolean, default_value=False),
)
args:
type (class for a graphene.UnmountedType): must be a class (not an instance) of an
unmounted graphene type (ex. scalar or object) which is used for the type of this
argument in the GraphQL schema.
required (bool): indicates this argument as not null in the graphql scehma. Same behavior
as graphene.NonNull. Default False.
name (str): the name of the GraphQL argument. Defaults to parameter name.
description (str): the description of the GraphQL argument in the schema.
default_value (Any): The value to be provided if the user does not set this argument in
the operation.
"""

def __init__(
self,
type,
Expand Down
21 changes: 21 additions & 0 deletions graphene/types/context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
class Context(object):
"""
Context can be used to make a convenient container for attributes to provide
for execution for resolvers of a GraphQL operation like a query.
.. code:: python
from graphene import Context
context = Context(loaders=build_dataloaders(), request=my_web_request)
schema.execute('{ hello(name: "world") }', context=context)
def resolve_hello(parent, info, name):
info.context.request # value set in Context
info.context.loaders # value set in Context
# ...
args:
**params (Dict[str, Any]): values to make available on Context instance as attributes.
"""

def __init__(self, **params):
for key, value in params.items():
setattr(self, key, value)
24 changes: 24 additions & 0 deletions graphene/types/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,30 @@ def from_enum(cls, enum, description=None, deprecation_reason=None): # noqa: N8


class Enum(six.with_metaclass(EnumMeta, UnmountedType, BaseType)):
"""
Enum type definition
Defines a static set of values that can be provided as a Field, Argument or InputField.
.. code:: python
from graphene import Enum
class NameFormat(Enum):
FIRST_LAST = "first_last"
LAST_FIRST = "last_first"
Meta:
enum (optional, Enum): Python enum to use as a base for GraphQL Enum.
name (optional, str): Name of the GraphQL type (must be unique in schema). Defaults to class
name.
description (optional, str): Description of the GraphQL type in the schema. Defaults to class
docstring.
deprecation_reason (optional, str): Setting this value indicates that the enum is
depreciated and may provide instruction or reason on how for clients to proceed.
"""

@classmethod
def __init_subclass_with_meta__(cls, enum=None, _meta=None, **options):
if not _meta:
Expand Down
41 changes: 41 additions & 0 deletions graphene/types/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,47 @@ def source_resolver(source, root, info, **args):


class Field(MountedType):
"""
Makes a field available on an ObjectType in the GraphQL schema. Any type can be mounted as a
Field:
- Object Type
- Scalar Type
- Enum
- Interface
- Union
All class attributes of ``graphene.ObjectType`` are implicitly mounted as Field using the below
arguments.
.. code:: python
class Person(ObjectType):
first_name = graphene.String(required=True) # implicitly mounted as Field
last_name = graphene.Field(String, description='Surname') # explicitly mounted as Field
args:
type (class for a graphene.UnmountedType): must be a class (not an instance) of an
unmounted graphene type (ex. scalar or object) which is used for the type of this
field in the GraphQL schema.
args (optional, Dict[str, graphene.Argument]): arguments that can be input to the field.
Prefer to use **extra_args.
resolver (optional, Callable): A function to get the value for a Field from the parent
value object. If not set, the default resolver method for the schema is used.
source (optional, str): attribute name to resolve for this field from the parent value
object. Alternative to resolver (cannot set both source and resolver).
deprecation_reason (optional, str): Setting this value indicates that the field is
depreciated and may provide instruction or reason on how for clients to proceed.
required (optional, bool): indicates this field as not null in the graphql scehma. Same behavior as
graphene.NonNull. Default False.
name (optional, str): the name of the GraphQL field (must be unique in a type). Defaults to attribute
name.
description (optional, str): the description of the GraphQL field in the schema.
default_value (optional, Any): Default value to resolve if none set from schema.
**extra_args (optional, Dict[str, Union[graphene.Argument, graphene.UnmountedType]): any
additional arguments to mount on the field.
"""

def __init__(
self,
type,
Expand Down
40 changes: 40 additions & 0 deletions graphene/types/inputfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@


class InputField(MountedType):
"""
Makes a field available on an ObjectType in the GraphQL schema. Any type can be mounted as a
Input Field except Interface and Union:
- Object Type
- Scalar Type
- Enum
Input object types also can't have arguments on their input fields, unlike regular ``graphene.Field``.
All class attributes of ``graphene.InputObjectType`` are implicitly mounted as InputField
using the below arguments.
.. code:: python
from graphene import InputObjectType, String, InputField
class Person(InputObjectType):
# implicitly mounted as Input Field
first_name = String(required=True)
# explicitly mounted as Input Field
last_name = InputField(String, description="Surname")
args:
type (class for a graphene.UnmountedType): Must be a class (not an instance) of an
unmounted graphene type (ex. scalar or object) which is used for the type of this
field in the GraphQL schema.
name (optional, str): Name of the GraphQL input field (must be unique in a type).
Defaults to attribute name.
default_value (optional, Any): Default value to use as input if none set in user operation (
query, mutation, etc.).
deprecation_reason (optional, str): Setting this value indicates that the field is
depreciated and may provide instruction or reason on how for clients to proceed.
description (optional, str): Description of the GraphQL field in the schema.
required (optional, bool): Indicates this input field as not null in the graphql scehma.
Raises a validation error if argument not provided. Same behavior as graphene.NonNull.
Default False.
**extra_args (optional, Dict): Not used.
"""

def __init__(
self,
type,
Expand Down

0 comments on commit da1359e

Please sign in to comment.