From 65c9cc7ce8fb6824d635b254cb205a0f0ff451ac Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 25 Nov 2015 15:25:03 -0800 Subject: [PATCH] Big improvements in docs pages --- .gitignore | 4 + .travis.yml | 15 +- docs/assets/edit.png | Bin 0 -> 372 bytes docs/assets/edit@2x.png | Bin 0 -> 688 bytes docs/config.toml | 18 +- docs/css/hljs.css | 70 +++++++ docs/css/main.styl | 182 ++++++++++++++++-- docs/gatsby.config.js | 3 +- docs/package.json | 2 +- docs/pages/_header.js | 11 +- docs/pages/_template.js | 6 +- docs/pages/community.md | 8 + docs/pages/docs/_template.js | 48 +++++ docs/pages/docs/basic-types.md | 52 +++++ .../interface.md => docs/interfaces.md} | 14 +- docs/pages/docs/mutations.md | 75 ++++++++ .../objecttype.md => docs/objecttypes.md} | 10 +- ...ngo_quickstart.md => quickstart-django.md} | 7 +- docs/pages/docs/quickstart.md | 9 +- docs/pages/guide/mutation.md | 67 ------- docs/pages/index.md | 2 +- docs/wrappers/md.js | 8 +- 22 files changed, 494 insertions(+), 117 deletions(-) create mode 100644 docs/assets/edit.png create mode 100644 docs/assets/edit@2x.png create mode 100644 docs/css/hljs.css create mode 100644 docs/pages/docs/_template.js create mode 100644 docs/pages/docs/basic-types.md rename docs/pages/{guide/interface.md => docs/interfaces.md} (76%) create mode 100644 docs/pages/docs/mutations.md rename docs/pages/{guide/objecttype.md => docs/objecttypes.md} (85%) rename docs/pages/docs/{django_quickstart.md => quickstart-django.md} (95%) delete mode 100644 docs/pages/guide/mutation.md diff --git a/.gitignore b/.gitignore index 57bee153..474bb31d 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,7 @@ target/ /tests/django.sqlite + +/graphene/index.json + +/graphene/meta.json diff --git a/.travis.yml b/.travis.yml index afc82b45..705ef0d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,22 +6,25 @@ python: - 3.4 - 3.5 - pypy +node_js: +- 4.1 cache: - - pip - - directories: + directories: - .cache/pip/ - - docs/node_modules + - $HOME/.cache/pip + - docs/node_modules/ + - $HOME/docs/node_modules install: -- pip install --download-cache .cache/pip/ pytest pytest-cov coveralls flake8 six +- pip install --download-cache $HOME/.cache/pip/ pytest pytest-cov coveralls flake8 six blinker pytest-django -- pip install --download-cache .cache/pip/ -e .[django] +- pip install --download-cache $HOME/.cache/pip/ -e .[django] - python setup.py develop script: - py.test --cov=graphene - flake8 after_success: - coveralls -- cd docs && npm run deploy +- nvm install 4.1 && cd docs && npm run deploy env: matrix: diff --git a/docs/assets/edit.png b/docs/assets/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..80646b2f41d00941f9ae328ec8dbee1ef7b41c09 GIT binary patch literal 372 zcmV-)0gL{LP)#H{y<^kYBlD!#4!6M6F*$n{nnncN5V6FfGaqI4cp+F;swbHX!c3ITEc++8N85l zhOSkRZxQw8O;%*$7qOWXSwh7CZCA6*bfXk?2KzKq)7kliJ)1r1mK6h%`m5&9M&a5B zZK(N(3kIBT;0tWQHz*XE^>A|CL}4i#+!t{Z*^gzS=e@`I7Yy;1sM9cg5Nm zW7S>(#yYkRESudTUgRKr<~`<%s)Zi~Ux2aON(E5WcEgG6A21>&8D9g5Y*i*e#r&c; ztEm&SekbM_x4aHpLUSL1ih*$3EoHr>ZyssrXEZb}G!!|BAHldofhO_6)1mlM0&`$~CvrGZRS3@ohF>*~)1yo5+tv9&@R80Pw zdVOaB6_am>T;?QzxX0j+5*#e~h8rCDTDXRj0RLX8lXwwMwv4mLpT%=h-vb1{09)V@ z&+jEd=E0!^Sx^ zOd|dXI3ejdozRu)|Nb1vT&{c&Y58>(pwua_hlmCu{xW_AdO)w&w6+tHY%YHw;cSWc zjEFj4R8bh1 + margin 0 + @extend $title + font-size 32px diff --git a/docs/gatsby.config.js b/docs/gatsby.config.js index 80be7b41..8aa39cdf 100644 --- a/docs/gatsby.config.js +++ b/docs/gatsby.config.js @@ -1,12 +1,13 @@ var nib = require("nib"); var jeet = require("jeet"); +var rupture = require("rupture"); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = function(config, env) { var IS_STATIC = env === 'static'; config.merge({ stylus: { - use: [nib(), jeet()] + use: [nib(), jeet(), rupture()] } }); if (IS_STATIC) { diff --git a/docs/package.json b/docs/package.json index 7ef2b3b9..2eeea26e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,7 @@ "main": "n/a", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "npm install -g gatsby && npm install", + "build": "npm install -g gatsby && npm install && gatsby build", "deploy": "npm run build" }, "keywords": [ diff --git a/docs/pages/_header.js b/docs/pages/_header.js index 9d70ef03..845a081d 100644 --- a/docs/pages/_header.js +++ b/docs/pages/_header.js @@ -1,6 +1,13 @@ var IN_BROWSER = typeof window != 'undefined'; import React from 'react'; +var browser_supported; if (IN_BROWSER) { + var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && + navigator.userAgent && !navigator.userAgent.match('CriOS'); + var browser_supported = !isSafari; +} +console.log(browser_supported); +if (IN_BROWSER && browser_supported) { var glfx = require('../vendor/glfx.optim') var particlesJS = require('../vendor/particles.js') } @@ -23,12 +30,12 @@ class Header extends React.Component { this.mounted = false; } componentDidMount() { - if (!IN_BROWSER) return; + if (!(IN_BROWSER && browser_supported)) return; this.mounted = true; new particlesJS('header-background', { "particles": { "number": { - "value": 36, + "value": 40, "density": { "enable": true, "value_area": 800 diff --git a/docs/pages/_template.js b/docs/pages/_template.js index e077d005..4d40b788 100644 --- a/docs/pages/_template.js +++ b/docs/pages/_template.js @@ -19,10 +19,10 @@ class Template extends React.Component { Graphene {isIndex? diff --git a/docs/pages/community.md b/docs/pages/community.md index 5ad38de1..c42f6b2b 100644 --- a/docs/pages/community.md +++ b/docs/pages/community.md @@ -17,9 +17,17 @@ If you think working with Graphene is fun, there are many ways you can contribut - **GraphQL Relay**: [Source Code][1] - [PyPI package][2] - **Graphene**: [Source Code][3] - [PyPI package][4] +Django integration: +- **graphql-django-view**: [Source Code][5] - [PyPI package][6] +- **django-graphiql**: [Source Code][7] - [PyPI package][8] + [Source Code]: https://github.com/graphql-python/graphql-core [PyPI package]: https://pypi.python.org/pypi/graphql-core [1]: https://github.com/graphql-python/graphql-relay [2]: https://pypi.python.org/pypi/graphql-relay [3]: https://github.com/graphql-python/graphene [4]: https://pypi.python.org/pypi/graphene + [5]: https://github.com/graphql-python/graphql-django-view + [6]: https://pypi.python.org/pypi/graphql-django-view + [7]: https://github.com/graphql-python/django-graphiql + [8]: https://pypi.python.org/pypi/django-graphiql diff --git a/docs/pages/docs/_template.js b/docs/pages/docs/_template.js new file mode 100644 index 00000000..c678e494 --- /dev/null +++ b/docs/pages/docs/_template.js @@ -0,0 +1,48 @@ +import React from 'react'; +import { RouteHandler, Link, State } from 'react-router'; +import _ from 'lodash'; + +class Template extends React.Component { + goToPage(event) { + var page = event.target.value; + this.context.router.transitionTo(page); + } + render() { + var docs = this.props.config.docs; + var docs_index = _.indexBy(this.props.pages, 'path'); + return ( +
+ +
+ +
+
+ ); + } +} + +Template.contextTypes = { + router: React.PropTypes.func +}; + +module.exports = Template; diff --git a/docs/pages/docs/basic-types.md b/docs/pages/docs/basic-types.md new file mode 100644 index 00000000..7a067942 --- /dev/null +++ b/docs/pages/docs/basic-types.md @@ -0,0 +1,52 @@ +--- +title: Basic Types +description: Walkthrough Basic Types +--- + +# Basic Types + +Graphene define the following base Types: +- `graphene.String` +- `graphene.Int` +- `graphene.Float` +- `graphene.Boolean` +- `graphene.ID` + +Also, define: +- `graphene.List` +- `graphene.NonNull` + +## Mounting in ClassTypes + +This types if are mounted in a `ObjectType`, `Interface` or `Mutation`, + would act as `Field`s. +So, the following examples will behave exactly the same: + +```python +class Person(graphene.ObjectType): + name = graphene.String() +``` +and + +```python +class Person(graphene.ObjectType): + name = graphene.Field(graphene.String()) +``` + +## Mounting in Fields + +If this types are mounted in a `Field`, would act as `Argument`s. +So, the following examples will behave exactly the same: + +```python +class Person(graphene.ObjectType): + say_hello = graphene.Field(graphene.String(), + to=graphene.String()) +``` +and + +```python +class Person(graphene.ObjectType): + say_hello = graphene.Field(graphene.String(), + to=graphene.Argument(graphene.String())) +``` diff --git a/docs/pages/guide/interface.md b/docs/pages/docs/interfaces.md similarity index 76% rename from docs/pages/guide/interface.md rename to docs/pages/docs/interfaces.md index 9f5ff2b9..43c2daf8 100644 --- a/docs/pages/guide/interface.md +++ b/docs/pages/docs/interfaces.md @@ -1,9 +1,13 @@ +--- +title: Interfaces +description: Walkthrough Interfaces +--- + # Interfaces An Interface contains the essential fields that will be shared among multiple ObjectTypes. The basics: - - Each Interface is a Python class that inherits from graphene.Interface. - Each attribute of the Interface represents a GraphQL field. @@ -16,19 +20,19 @@ import graphene # Character is an Interface class Character(graphene.Interface): - name = graphene.String() + name = graphene.String() # Human is an ObjectType, as inherits an interface class Human(Character): - born_in = graphene.String() + born_in = graphene.String() # Droid is an ObjectType, as inherits an interface class Droid(Character): - function = graphene.String() + function = graphene.String() ``` -**name** is a field in the `Character` interface that will be in both `Human` and `Droid` ObjectTypes (as those inherit from Character). Each ObjectType also define extra fields at the same time. +**name** is a field in the `Character` interface that will be in both `Human` and `Droid` ObjectTypes (as those inherit from `Character`). Each ObjectType also define extra fields at the same time. The above types would have the following representation in a schema: diff --git a/docs/pages/docs/mutations.md b/docs/pages/docs/mutations.md new file mode 100644 index 00000000..7967f62c --- /dev/null +++ b/docs/pages/docs/mutations.md @@ -0,0 +1,75 @@ +--- +title: Mutations +description: Walkthrough Mutations +--- + +# Mutations + +A Mutation is a special ObjectType that define also an Input. + +## Quick example + +This example defines a Mutation: + +```python +import graphene + +class CreatePerson(graphene.Mutation): + class Input: + name = graphene.String() + + ok = graphene.String() + person = graphene.Field('Person') + + @classmethod + def mutate(cls, args, info): + person = Person(name=args.get('name')) + ok = True + return CreatePerson(person=person, ok=ok) +``` + +**person** and **ok** are the output fields of the Mutation when is resolved. + +**Input** attributes are the arguments that the Mutation `CreatePerson` needs for resolving, in this case **name** will be the only argument for the mutation. + +**mutate** is the function that will be applied once the mutation is called. + +So, we can finish our schema like this: + +```python +# ... the Mutation Class + +class Person(graphene.ObjectType): + name = graphene.String() + +class MyMutations(graphene.ObjectType): + create_person = graphene.Field(CreatePerson) + +schema = graphene.Schema(mutation=MyMutations) +``` + +## Executing the Mutation + +Then, if we query (`schema.execute(query_str)`) the following: +```graphql +mutation myFirstMutation { + createPerson(name:"Peter") { + person { + name + } + ok + } +} +``` + +We should receive: + +```json +{ + "createPerson": { + "person" : { + name: "Peter" + }, + "ok": true + } +} diff --git a/docs/pages/guide/objecttype.md b/docs/pages/docs/objecttypes.md similarity index 85% rename from docs/pages/guide/objecttype.md rename to docs/pages/docs/objecttypes.md index 191094ae..dbcab0f3 100644 --- a/docs/pages/guide/objecttype.md +++ b/docs/pages/docs/objecttypes.md @@ -1,10 +1,14 @@ +--- +title: ObjectTypes +description: Walkthrough ObjectTypes +--- + # ObjectTypes An ObjectType is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re querying. The basics: - -- Each ObjectType is a Python class that inherits graphene.ObjectType or inherits an implemented [interface](/docs/interface). +- Each ObjectType is a Python class that inherits graphene.ObjectType or inherits an implemented [interfaces](/docs/interfaces/). - Each attribute of the ObjectType represents a GraphQL field. ## Quick example @@ -20,7 +24,7 @@ class Person(graphene.ObjectType): full_name = graphene.String() def resolve_full_name(self, args, info): - return '{} {}'.format(self.first_name, self.last_name) + return '{} {}'.format(self.first_name, self.last_name) ``` **first_name** and **last_name** are fields of the ObjectType. Each field is specified as a class attribute, and each attribute maps to a GraphQL field. diff --git a/docs/pages/docs/django_quickstart.md b/docs/pages/docs/quickstart-django.md similarity index 95% rename from docs/pages/docs/django_quickstart.md rename to docs/pages/docs/quickstart-django.md index e88fbcdf..542854e7 100644 --- a/docs/pages/docs/django_quickstart.md +++ b/docs/pages/docs/quickstart-django.md @@ -1,13 +1,10 @@ --- -title: Django Quickstart Guide -active_tab: quickstart +title: Guide to Django description: A Quick guide to Graphene in Django --- -## Django Quickstart - In our previous quickstart page we created a very simple schema. -Now we will adapt the schema for our Django models. +Now we will adapt the schema to map automatically some Django models. ## Project setup diff --git a/docs/pages/docs/quickstart.md b/docs/pages/docs/quickstart.md index f408a851..f2c56f03 100644 --- a/docs/pages/docs/quickstart.md +++ b/docs/pages/docs/quickstart.md @@ -1,10 +1,10 @@ --- -title: Quickstart Guide -active_tab: quickstart +title: Getting started description: A Quick guide to Graphene --- -Graphene is a powerful framework for creating GraphQL schemas easily in Python. +Let's build a basic GraphQL schema from scratch. + ## Requirements @@ -23,6 +23,7 @@ cd tutorial virtualenv env source env/bin/activate # On Windows use `env\Scripts\activate` +# Install Graphene pip install graphene ``` @@ -30,7 +31,7 @@ pip install graphene A GraphQL schema describes your data model, and provides a GraphQL server with an associated set of resolve methods that know how to fetch data. -We are going to create a very simple schema, with a `Query` with only one field: `hello`. And when we query it should return 'World'. +We are going to create a very simple schema, with a `Query` with only one field: `hello`. And when we query it should return `"World"`. ```python diff --git a/docs/pages/guide/mutation.md b/docs/pages/guide/mutation.md deleted file mode 100644 index 788cadfd..00000000 --- a/docs/pages/guide/mutation.md +++ /dev/null @@ -1,67 +0,0 @@ -# Mutations - -A Mutation is a special ObjectType that define also an Input. - -## Quick example - -This example model defines a Mutation: - -```python -import graphene - -class CreatePerson(graphene.Mutation): - class Input: - name = graphene.String() - - ok = graphene.String() - person = graphene.Field('Person') - - @classmethod - def mutate(cls, args, info): - person = Person(name=args.get('name')) - ok = True - return CreatePerson(person=person, ok=ok) -``` - -**person** and **ok** are the output fields of the Mutation when is resolved. -**Input** attributes are the arguments that the Mutation needs for resolving. **mutate** is the function that will be applied once the mutation is called. - -So, we can finish our schema like this: - -```python -# ... the Mutation Class - -class Person(graphene.ObjectType): - name = graphene.String() - -class MyMutations(graphene.ObjectType): - create_person = graphene.Field(CreatePerson) - -schema = graphene.Schema(mutation=MyMutations) -``` - -## Executing the Mutation - -Then, if we query (`schema.execute(query_str)`) the following: -```graphql -mutation myFirstMutation { - createPerson(name:"Peter") { - person { - name - } - ok - } -} -``` - -We should receive: - -```json -{ - "createPerson": { - "person" : { - name: "Peter" - }, - "ok": true - } -} diff --git a/docs/pages/index.md b/docs/pages/index.md index 80444d40..359e512b 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -1,7 +1,7 @@ --- path: / --- -Check our starwars API example! + ## About Graphene diff --git a/docs/wrappers/md.js b/docs/wrappers/md.js index ddde3df8..b34806c3 100644 --- a/docs/wrappers/md.js +++ b/docs/wrappers/md.js @@ -9,15 +9,15 @@ class Markdown extends React.Component { var post = this.props.page.data; var pagePath = this.props.page.requirePath; var documentUrl = `${DOCS_BASEURL}${pagePath}`; - + var showTitle = post.title && !this.props.docs; return (
- {post.title?
+ {showTitle?

{post.title}

:null} -