Skip to content

Commit 2df4fad

Browse files
committed
[v0.2.0] Release v0.2.0!
1 parent 725a728 commit 2df4fad

File tree

3 files changed

+104
-56
lines changed

3 files changed

+104
-56
lines changed

README.md

Lines changed: 94 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@ Epoxy is a magical tool for rapid development of GraphQL types, schemas, resolve
77
* **Quick**: Once you create your schema, epoxy doesn't get in the way. Your resolvers will be called directly by
88
`graphql-core` with no additional indirection.
99

10-
This codebase is currently a **WORK IN PROGRESS**, and is currently at alpha stages. The API may change without notice.
11-
If you're looking for a more stable pythonic `graphql-core` wrapper, check out
12-
[`graphene`](https://github.com/graphql-python/graphene).
13-
1410
## Installation
1511

1612
Epoxy is available on pypi under the package name `graphql-epoxy`, you can get it by running:
1713

1814
```sh
19-
pip install graphql-epoxy==0.1a0
15+
pip install graphql-epoxy
2016
```
2117

2218
## Usage
@@ -164,6 +160,99 @@ class RealHumanBean(models.Model):
164160
R.Human.CanBe(Human)
165161
```
166162

163+
164+
## Mutations
165+
166+
Epoxy also supports defining mutations. Making a Mutation a Relay mutation is as simple as changing `R.Mutation` to
167+
`Relay.Mutation`.
168+
169+
170+
```python
171+
172+
class AddFriend(R.Mutation):
173+
class Input:
174+
human_to_add = R.ID.NonNull
175+
176+
class Output:
177+
new_friends_list = R.Human.List
178+
179+
@R.resolve_with_args
180+
def resolve(self, obj, human_to_add):
181+
obj.add_friend(human_to_add)
182+
return self.Output(new_friends_list=obj.friends)
183+
184+
185+
schema = R.schema(R.Query, R.Mutations)
186+
187+
```
188+
189+
You can then execute the query:
190+
191+
192+
```graphql
193+
mutation AddFriend {
194+
addFriend(input: {humanToAdd: 6}) {
195+
newFriendsList {
196+
id
197+
name
198+
homePlanet
199+
}
200+
}
201+
}
202+
```
203+
204+
## Defining custom scalar types:
205+
206+
207+
```python
208+
class DateTime(R.Scalar):
209+
@staticmethod
210+
def serialize(dt):
211+
return dt.isoformat()
212+
213+
@staticmethod
214+
def parse_literal(node):
215+
if isinstance(node, ast.StringValue):
216+
return datetime.datetime.strptime(node.value, "%Y-%m-%dT%H:%M:%S.%f")
217+
218+
@staticmethod
219+
def parse_value(value):
220+
return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
221+
222+
```
223+
224+
## Defining input types:
225+
226+
```python
227+
class SimpleInput(R.InputType):
228+
a = R.Int
229+
b = R.Int
230+
some_underscore = R.String
231+
some_from_field = R.String(default_value='Hello World')
232+
233+
```
234+
235+
## Defining an Enum (using `enum` module)
236+
237+
```python
238+
239+
from enum import Enum
240+
241+
@R
242+
class MyEnum(Enum):
243+
FOO = 1
244+
BAR = 2
245+
BAZ = 3
246+
247+
```
248+
249+
### Starwars?!
250+
Use the force, check out how we've defined the
251+
[schema](https://github.com/graphql-python/graphql-epoxy/blob/master/tests/test_starwars/schema.py)
252+
for the starwars tests, and compare them to the reference implementation's
253+
[schema](https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsSchema.js).
254+
255+
167256
## Relay Support
168257

169258
At this point, Epoxy has rudimentary `relay` support. Enable support for `Relay` by mixing in the `RelayMixin` using
@@ -264,50 +353,3 @@ result = graphql(Schema, '''
264353
}
265354
''')
266355
```
267-
268-
269-
## Mutations
270-
271-
Epoxy also supports defining mutations. Making a Mutation a Relay mutation is as simple as changing `R.Mutation` to
272-
`Relay.Mutation`.
273-
274-
275-
```python
276-
277-
class AddFriend(R.Mutation):
278-
class Input:
279-
human_to_add = R.ID.NonNull
280-
281-
class Output:
282-
new_friends_list = R.Human.List
283-
284-
@R.resolve_with_args
285-
def resolve(self, obj, human_to_add):
286-
obj.add_friend(human_to_add)
287-
return self.Output(new_friends_list=obj.friends)
288-
289-
290-
schema = R.schema(R.Query, R.Mutations)
291-
292-
```
293-
294-
You can then execute the query:
295-
296-
297-
```graphql
298-
mutation AddFriend {
299-
addFriend(input: {humanToAdd: 6}) {
300-
newFriendsList {
301-
id
302-
name
303-
homePlanet
304-
}
305-
}
306-
}
307-
```
308-
309-
310-
311-
312-
313-

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111

1212
setup(
1313
name='graphql-epoxy',
14-
version='0.2a3',
14+
version='0.2',
1515
description='GraphQL implementation for Python',
1616
url='https://github.com/graphql-python/graphql-core',
1717
download_url='https://github.com/graphql-python/graphql-core/releases',
1818
author='Jake Heinz',
1919
author_email='me' '@' 'jh.gg',
2020
license='MIT',
2121
classifiers=[
22-
'Development Status :: 3 - Alpha',
22+
'Development Status :: 5 - Production/Stable',
2323
'Intended Audience :: Developers',
2424
'Topic :: Software Development :: Libraries',
2525
'Programming Language :: Python :: 2',

tests/test_input_type.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,24 @@ class SimpleInput(R.InputType):
1212
b = R.Int
1313
some_underscore = R.String
1414
some_from_field = R.InputField(R.String, default_value='Hello World')
15+
default_value_from_thunk = R.String(default_value='Hello World')
1516

1617
input_type = SimpleInput.T
1718
assert input_type is R.SimpleInput()
1819
assert isinstance(input_type, GraphQLInputObjectType)
1920
fields = input_type.get_fields()
20-
assert list(fields.keys()) == ['a', 'b', 'someUnderscore', 'someFromField']
21-
assert [field.name for field in fields.values()] == ['a', 'b', 'someUnderscore', 'someFromField']
2221

22+
expected_keys = ['a', 'b', 'someUnderscore', 'someFromField', 'defaultValueFromThunk']
23+
24+
assert list(fields.keys()) == expected_keys
25+
assert [field.name for field in fields.values()] == expected_keys
2326
assert fields['a'].type == GraphQLInt
2427
assert fields['b'].type == GraphQLInt
2528
assert fields['someUnderscore'].type == GraphQLString
2629
assert fields['someFromField'].type == GraphQLString
2730
assert fields['someFromField'].default_value == 'Hello World'
31+
assert fields['defaultValueFromThunk'].type == GraphQLString
32+
assert fields['defaultValueFromThunk'].default_value == 'Hello World'
2833

2934
input_value = SimpleInput({
3035
'a': 1,
@@ -35,6 +40,7 @@ class SimpleInput(R.InputType):
3540
assert input_value.b is None
3641
assert input_value.some_underscore == 'hello'
3742
assert input_value.some_from_field == 'Hello World'
43+
assert input_value.default_value_from_thunk == 'Hello World'
3844

3945

4046
def test_input_type():

0 commit comments

Comments
 (0)