Skip to content

Commit d042d5e

Browse files
authored
Expose Base64 type and add custom scalar examples (#1223)
1 parent c61f0f7 commit d042d5e

File tree

4 files changed

+267
-95
lines changed

4 files changed

+267
-95
lines changed

docs/api/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Graphene Scalars
6464

6565
.. autoclass:: graphene.JSONString()
6666

67+
.. autoclass:: graphene.Base64()
68+
6769
Enum
6870
----
6971

docs/types/scalars.rst

Lines changed: 177 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Scalars
44
=======
55

6+
Scalar types represent concrete values at the leaves of a query. There are
7+
several built in types that Graphene provides out of the box which represent common
8+
values in Python. You can also create your own Scalar types to better express
9+
values that you might have in your data model.
10+
611
All Scalar types accept the following arguments. All are optional:
712

813
``name``: *string*
@@ -27,59 +32,223 @@ All Scalar types accept the following arguments. All are optional:
2732

2833

2934

30-
Base scalars
31-
------------
35+
Built in scalars
36+
----------------
3237

33-
Graphene defines the following base Scalar Types:
38+
Graphene defines the following base Scalar Types that match the default `GraphQL types <https://graphql.org/learn/schema/#scalar-types>`_:
3439

3540
``graphene.String``
41+
^^^^^^^^^^^^^^^^^^^
3642

3743
Represents textual data, represented as UTF-8
3844
character sequences. The String type is most often used by GraphQL to
3945
represent free-form human-readable text.
4046

4147
``graphene.Int``
48+
^^^^^^^^^^^^^^^^
4249

4350
Represents non-fractional signed whole numeric
4451
values. Int is a signed 32‐bit integer per the
4552
`GraphQL spec <https://facebook.github.io/graphql/June2018/#sec-Int>`_
4653

4754
``graphene.Float``
55+
^^^^^^^^^^^^^^^^^^
4856

4957
Represents signed double-precision fractional
5058
values as specified by
5159
`IEEE 754 <http://en.wikipedia.org/wiki/IEEE_floating_point>`_.
5260

5361
``graphene.Boolean``
62+
^^^^^^^^^^^^^^^^^^^^
5463

5564
Represents `true` or `false`.
5665

5766
``graphene.ID``
67+
^^^^^^^^^^^^^^^
5868

5969
Represents a unique identifier, often used to
6070
refetch an object or as key for a cache. The ID type appears in a JSON
6171
response as a String; however, it is not intended to be human-readable.
6272
When expected as an input type, any string (such as `"4"`) or integer
6373
(such as `4`) input value will be accepted as an ID.
6474

65-
Graphene also provides custom scalars for Dates, Times, and JSON:
75+
----
6676

67-
``graphene.types.datetime.Date``
77+
Graphene also provides custom scalars for common values:
78+
79+
``graphene.Date``
80+
^^^^^^^^^^^^^^^^^
6881

6982
Represents a Date value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.
7083

71-
``graphene.types.datetime.DateTime``
84+
.. code:: python
85+
86+
import datetime
87+
from graphene import Schema, ObjectType, Date
88+
89+
class Query(ObjectType):
90+
one_week_from = Date(required=True, date_input=Date(required=True))
91+
92+
def resolve_one_week_from(root, info, date_input):
93+
assert date_input == datetime.date(2006, 1, 2)
94+
return date_input + datetime.timedelta(weeks=1)
95+
96+
schema = Schema(query=Query)
97+
98+
results = schema.execute("""
99+
query {
100+
oneWeekFrom(dateInput: "2006-01-02")
101+
}
102+
""")
103+
104+
assert results.data == {"oneWeekFrom": "2006-01-09"}
105+
106+
107+
``graphene.DateTime``
108+
^^^^^^^^^^^^^^^^^^^^^
72109

73110
Represents a DateTime value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.
74111

75-
``graphene.types.datetime.Time``
112+
.. code:: python
113+
114+
import datetime
115+
from graphene import Schema, ObjectType, DateTime
116+
117+
class Query(ObjectType):
118+
one_hour_from = DateTime(required=True, datetime_input=DateTime(required=True))
119+
120+
def resolve_one_hour_from(root, info, datetime_input):
121+
assert datetime_input == datetime.datetime(2006, 1, 2, 15, 4, 5)
122+
return datetime_input + datetime.timedelta(hours=1)
123+
124+
schema = Schema(query=Query)
125+
126+
results = schema.execute("""
127+
query {
128+
oneHourFrom(datetimeInput: "2006-01-02T15:04:05")
129+
}
130+
""")
131+
132+
assert results.data == {"oneHourFrom": "2006-01-02T16:04:05"}
133+
134+
``graphene.Time``
135+
^^^^^^^^^^^^^^^^^
76136

77137
Represents a Time value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.
78138

79-
``graphene.types.json.JSONString``
139+
.. code:: python
140+
141+
import datetime
142+
from graphene import Schema, ObjectType, Time
143+
144+
class Query(ObjectType):
145+
one_hour_from = Time(required=True, time_input=Time(required=True))
146+
147+
def resolve_one_hour_from(root, info, time_input):
148+
assert time_input == datetime.time(15, 4, 5)
149+
tmp_time_input = datetime.datetime.combine(datetime.date(1, 1, 1), time_input)
150+
return (tmp_time_input + datetime.timedelta(hours=1)).time()
151+
152+
schema = Schema(query=Query)
153+
154+
results = schema.execute("""
155+
query {
156+
oneHourFrom(timeInput: "15:04:05")
157+
}
158+
""")
159+
160+
assert results.data == {"oneHourFrom": "16:04:05"}
161+
162+
``graphene.Decimal``
163+
^^^^^^^^^^^^^^^^^^^^
164+
165+
Represents a Python Decimal value.
166+
167+
.. code:: python
168+
169+
import decimal
170+
from graphene import Schema, ObjectType, Decimal
171+
172+
class Query(ObjectType):
173+
add_one_to = Decimal(required=True, decimal_input=Decimal(required=True))
174+
175+
def resolve_add_one_to(root, info, decimal_input):
176+
assert decimal_input == decimal.Decimal("10.50")
177+
return decimal_input + decimal.Decimal("1")
178+
179+
schema = Schema(query=Query)
180+
181+
results = schema.execute("""
182+
query {
183+
addOneTo(decimalInput: "10.50")
184+
}
185+
""")
186+
187+
assert results.data == {"addOneTo": "11.50"}
188+
189+
``graphene.JSONString``
190+
^^^^^^^^^^^^^^^^^^^^^^^
80191

81192
Represents a JSON string.
82193

194+
.. code:: python
195+
196+
from graphene import Schema, ObjectType, JSONString, String
197+
198+
class Query(ObjectType):
199+
update_json_key = JSONString(
200+
required=True,
201+
json_input=JSONString(required=True),
202+
key=String(required=True),
203+
value=String(required=True)
204+
)
205+
206+
def resolve_update_json_key(root, info, json_input, key, value):
207+
assert json_input == {"name": "Jane"}
208+
json_input[key] = value
209+
return json_input
210+
211+
schema = Schema(query=Query)
212+
213+
results = schema.execute("""
214+
query {
215+
updateJsonKey(jsonInput: "{\\"name\\": \\"Jane\\"}", key: "name", value: "Beth")
216+
}
217+
""")
218+
219+
assert results.data == {"updateJsonKey": "{\"name\": \"Beth\"}"}
220+
221+
222+
``graphene.Base64``
223+
^^^^^^^^^^^^^^^^^^^
224+
225+
Represents a Base64 encoded string.
226+
227+
.. code:: python
228+
229+
from graphene import Schema, ObjectType, Base64
230+
231+
class Query(ObjectType):
232+
increment_encoded_id = Base64(
233+
required=True,
234+
base64_input=Base64(required=True),
235+
)
236+
237+
def resolve_increment_encoded_id(root, info, base64_input):
238+
assert base64_input == "4"
239+
return int(base64_input) + 1
240+
241+
schema = Schema(query=Query)
242+
243+
results = schema.execute("""
244+
query {
245+
incrementEncodedId(base64Input: "NA==")
246+
}
247+
""")
248+
249+
assert results.data == {"incrementEncodedId": "NQ=="}
250+
251+
83252
84253
Custom scalars
85254
--------------

graphene/__init__.py

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,45 @@
11
from .pyutils.version import get_version
2-
2+
from .relay import (
3+
ClientIDMutation,
4+
Connection,
5+
ConnectionField,
6+
GlobalID,
7+
Node,
8+
PageInfo,
9+
is_node,
10+
)
311
from .types import (
4-
ObjectType,
5-
InputObjectType,
6-
Interface,
7-
Mutation,
8-
Field,
9-
InputField,
10-
Schema,
11-
Scalar,
12-
String,
1312
ID,
14-
Int,
15-
Float,
13+
UUID,
14+
Argument,
15+
Base64,
1616
Boolean,
17+
Context,
1718
Date,
1819
DateTime,
19-
Time,
2020
Decimal,
21+
Dynamic,
22+
Enum,
23+
Field,
24+
Float,
25+
InputField,
26+
InputObjectType,
27+
Int,
28+
Interface,
2129
JSONString,
22-
UUID,
2330
List,
31+
Mutation,
2432
NonNull,
25-
Enum,
26-
Argument,
27-
Dynamic,
28-
Union,
29-
Context,
33+
ObjectType,
3034
ResolveInfo,
35+
Scalar,
36+
Schema,
37+
String,
38+
Time,
39+
Union,
3140
)
32-
from .relay import (
33-
Node,
34-
is_node,
35-
GlobalID,
36-
ClientIDMutation,
37-
Connection,
38-
ConnectionField,
39-
PageInfo,
40-
)
41-
from .utils.resolve_only_args import resolve_only_args
4241
from .utils.module_loading import lazy_import
43-
42+
from .utils.resolve_only_args import resolve_only_args
4443

4544
VERSION = (3, 0, 0, "beta", 3)
4645

@@ -49,40 +48,41 @@
4948

5049
__all__ = [
5150
"__version__",
52-
"ObjectType",
53-
"InputObjectType",
54-
"Interface",
55-
"Mutation",
56-
"Field",
57-
"InputField",
58-
"Schema",
59-
"Scalar",
60-
"String",
61-
"ID",
62-
"Int",
63-
"Float",
64-
"Enum",
51+
"Argument",
52+
"Base64",
6553
"Boolean",
54+
"ClientIDMutation",
55+
"Connection",
56+
"ConnectionField",
57+
"Context",
6658
"Date",
6759
"DateTime",
68-
"Time",
6960
"Decimal",
61+
"Dynamic",
62+
"Enum",
63+
"Field",
64+
"Float",
65+
"GlobalID",
66+
"ID",
67+
"InputField",
68+
"InputObjectType",
69+
"Int",
70+
"Interface",
7071
"JSONString",
71-
"UUID",
7272
"List",
73+
"Mutation",
74+
"Node",
7375
"NonNull",
74-
"Argument",
75-
"Dynamic",
76+
"ObjectType",
77+
"PageInfo",
78+
"ResolveInfo",
79+
"Scalar",
80+
"Schema",
81+
"String",
82+
"Time",
83+
"UUID",
7684
"Union",
77-
"resolve_only_args",
78-
"Node",
7985
"is_node",
80-
"GlobalID",
81-
"ClientIDMutation",
82-
"Connection",
83-
"ConnectionField",
84-
"PageInfo",
8586
"lazy_import",
86-
"Context",
87-
"ResolveInfo",
87+
"resolve_only_args",
8888
]

0 commit comments

Comments
 (0)