Releases: graphql-python/graphene
v3.3.0
This release brings two new features and several fixes and semantic upgrades due to new Python features. Thanks to everyone that contributed! 😊
Default value for InputObjectTypes
In GraphQL, inputs can have fields which are optional. Currently, if those fields are not specified in the query, they are passed to the python inputs as None
. This renders them indistinguishable from fields that are actually passed to the query with a value of null
. While the alternative would be to check the definition via "key" in input
, it is more accessible to mark these fields as explicitly UNDEFINED
.
This PR adds a new global override, which allows unspecified fields to be set to graphql.UNDEFINED
. In the future, the default Value will be set to UNDEFINED
, making this a soft migration and deprecation of the previous situation.
This is a soft migration. Long-Term, the Input Objects will ALWAYS contain the value UNDEFINED
Make sure your code supports these cases in None
checks. After the default has been set to UNDEFINED
, you will still be able to switch back to None
for the foreseeable future.
Strict connection types support in Relay
Custom Relay connection classes can now be made NonNull
using the strict_types
option on the connection meta.
Using this example
class MyObjectConnection(Connection):
class Meta:
node = MyObject
strict_types = True
will change from
type MyObjectConnection {
edges: [MyObjectEdge]
}
to
type MyObjectConnection {
edges: [MyObjectEdge!]!
}
Caveats
We want to make sure you're informed about using NonNull relay connections. While they are a great way to get rid of some null checks in typed frontends, it's important to be mindful of error handling with these connections. When working with NonNull connections, it's crucial to remember that if a requested field or edge is not available or the resolver throws an error, the error will bubble up to the next nullable parent field, which is oftentimes the root node. That way, you cannot handle partial results in case of partial errors anymore. In a nullable connection, only the nullable fields will be set to null and the error will not bubble up.
To address this, we recommend considering waiting for the future release of client-controlled nullability for cases where certain connections might be nullable. By opting for client-controlled nullability, you gain more control over error handling, enabling you to handle potential null values more gracefully and enhance the overall user experience. Read more about client controlled nullability here: graphql/graphql-spec#867
What's Changed
- Default enum description to "An enumeration." by @firaskafri in #1502
- Allow the user to change InputObjectType's default value on non-specified inputs to a sentinel value by @flipbit03 in #1506
- 881: Corrected enum metaclass to fix pickle.dumps() by @senseysensor in #1495
- chore: Use
typing.TYPE_CHECKING
instead of MYPY by @rapsealk in #1503 - test: print schema with InputObjectType with DateTime field with default_value (#1293) by @ransomw in #1513
- docs: add get_human function by @conao3 in #1380
- CI: drop python 3.6 by @dulmandakh in #1507
- types: add option for strict connection types by @shrouxm in #1504
New Contributors
- @firaskafri made their first contribution in #1502
- @senseysensor made their first contribution in #1495
- @rapsealk made their first contribution in #1503
- @ransomw made their first contribution in #1513
- @dulmandakh made their first contribution in #1507
- @shrouxm made their first contribution in #1504
Full Changelog: v3.2.2...v3.3.0
v3.2.2
v3.2.1
What's Changed
Non-required InputFields
and Arguments
can now be marked as deprecated by passing the deprecation_reason
keyword argument to the constructor.
New Contributors
Full Changelog: v3.2.0...v3.2.1
v3.2.0
What's Changed
Support for custom global IDs in relay.Node
The global ID type of a Node
can now be customized:
class CustomNode(Node):
class Meta:
global_id_type = CustomGlobalIDType
class User(ObjectType):
class Meta:
interfaces = [CustomNode]
name = String()
@classmethod
def get_node(cls, _type, _id):
return self.users[_id]
Available Types
Currently, the following types are available:
DefaultGlobalIDType
: Default global ID type: base64 encoded version of ": ". (Previously the only option) Scalar:ID
SimpleGlobalIDType
: Simple global ID type: simply the id of the object. Scalar:ID
UUIDGlobalIDType
: UUID global ID type. Scalar:UUID
Customization
To create a custom global type, BaseGlobalIDType
must be extended:
class CustomGlobalIDType(BaseGlobalIDType):
graphene_type = CustomScalar
@classmethod
def resolve_global_id(cls, info, global_id):
_type = custom_get_type_from_global_id(global_id)
return _type, global_id
@classmethod
def to_global_id(cls, _type, _id):
return _id
graphene_type
specifies the type of scalar to be used in the schema. Remember, that if you're using ID
as a scalar, you might need to deserialize your custom global ID first!
Relevant PR:
- feat: Add support for custom global (Issue #1276) by @tcleonard in #1428
Fixes & Improvements:
- Regression fix: (graphene 2->3)
ObjectTypes
can be copied again #1333 by @keu210 - Fix: Enums can now have members called
description
: #1478 by @mike-roberts-healx - Enums are now hashable: #1461 by @bkad
- Enums are now iterable: #1473 by @rgroothuijsen
- Dependency on unused promise Library was removed: #1476 by @mike-roberts-healx
- Docs improvements by @rgroothuijsen
All Changes
- feat: Add support for custom global (Issue #1276) by @tcleonard in #1428
- Add copy function for GrapheneGraphQLType by @keu210 in #1463
- hashable Enum by @bkad in #1461
- Clarify execution order in middleware docs by @rgroothuijsen in #1475
- fix: MyPy findings due to a mypy version upgrade were corrected by @erikwrede in #1477
- Disambiguate argument name in quickstart docs by @rgroothuijsen in #1474
- Make Graphene enums iterable like Python enums by @rgroothuijsen in #1473
- Remove unnecessary dependency on 'promise' library by @mike-roberts-healx in #1476
- Do not interpret Enum members called 'description' as description properties by @mike-roberts-healx in #1478
New Contributors
- @keu210 made their first contribution in #1463
- @bkad made their first contribution in #1461
- @rgroothuijsen made their first contribution in #1475
- @mike-roberts-healx made their first contribution in #1476
Full Changelog: v3.1.1...v3.2.0
v3.1.1
What's changed
Dataloader
Graphene now includes an updated version of aiodataloader
by Syrus Akbary under graphene.utils.dataloader
due to inactivity of the old repository. The update fixes an issue some users experienced when trying to use dataloader
in conjunction with pytest (syrusakbary/aiodataloader#13). Further contributions and updates to dataloader in this repo are welcome!
Enums
A custom typename can now be added when using from_enum
:
from enum import Enum as PyEnum
class Color(PyEnum):
RED = 1
YELLOW = 2
BLUE = 3
GColor = Enum.from_enum(Color, description="original colors")
UniqueGColor = Enum.from_enum(
Color, name="UniqueColor", description="unique colors"
)
type Query {
color: Color!
uniqueColor: UniqueColor!
}
"""original colors"""
enum Color {
RED
YELLOW
BLUE
}
"""unique colors"""
enum UniqueColor {
RED
YELLOW
BLUE
}
- feat: add ability to provide a type name to enum when using from_enum by @tcleonard in #1430
Interfaces
Interfaces extending interfaces is now supported!
class FooInterface(Interface):
foo = String()
class BarInterface(Interface):
class Meta:
interfaces = [FooInterface]
foo = String()
bar = String()
interface FooInterface {
foo: String
}
interface BarInterface implements FooInterface {
foo: String
bar: String
}
- Add support for interfaces on interfaces by @AlecRosenbaum in #1304
Thank you to everyone that contributed to this release!
Other Changes
- Fix typo in union comments by @ramonwenger in #1424
- Add Codecov to github actions by @erikwrede in #1431
- docs: Fix a few typos by @timgates42 in #1437
- Highlight .get in backticks by @RJ722 in #1402
- Add support for interfaces on interfaces by @AlecRosenbaum in #1304
- Update Dataloader docs [Waiting for Graphene v3 to be live] by @jkimbo in #1190
- Avoid ambiguity in graphene.Mutation docstring [documentation] by @belkka in #1381
- Issue #1413 fix invalid input type by @tcleonard in #1414
- Delete coveralls.yml by @erikwrede in #1442
- fix: use install instead of instal for consistency by @karmingc in #1444
- Update quickstart.rst by @alimcmaster1 in #1407
- Update pre-commit hooks by @ulgens in #1447
- fix: update ariadne url to the new docs by @DrewHoo in #1370
- Add Python 3.11 release candidate 1 to the testing by @cclauss in #1450
- Remove duplicate flake8 call in tox, it's covered by pre-commit by @ulgens in #1448
- Fix BigInt export by @erikwrede in #1456
- Upgrade base Python version to 3.10 by @ulgens in #1449
- Upgrade GitHub Actions by @cclauss in #1457
- Vendor
DataLoader
fromaiodataloader
and moveget_event_loop()
out of__init__
function. by @flipbit03 in #1459
New Contributors
- @ramonwenger made their first contribution in #1424
- @timgates42 made their first contribution in #1437
- @RJ722 made their first contribution in #1402
- @belkka made their first contribution in #1381
- @karmingc made their first contribution in #1444
- @alimcmaster1 made their first contribution in #1407
- @ulgens made their first contribution in #1447
- @DrewHoo made their first contribution in #1370
- @flipbit03 made their first contribution in #1459
Full Changelog: v3.1.0...v3.1.1
v3.1.0
What's Changed
- Various spelling and grammar fixes for the documentation. by @justinrmiller in #1324
- Chore: Refactor Multi Expression Code ✨ by @yezz123 in #1387
- Add Python 3.9 and 3.10 to the test matrix by @Cito in #1401
- fix UPGRADE-v2.0.md by @conao3 in #1405
- fix: default value for argument should be Undefined (Issue #1394) by @tcleonard in #1412
- fix: add default param _variables to parse_literal #1419 by @fugal-dy in #1420
- Make Graphene compatible with GraphQL-Core 3.2 by @Cito in #1421
New Contributors
- @justinrmiller made their first contribution in #1324
- @yezz123 made their first contribution in #1387
- @conao3 made their first contribution in #1405
- @fugal-dy made their first contribution in #1420
Full Changelog: v3.0.0...v3.1.0
v3.0.0
Release notes
The full release notes including an upgrade guide can be found here: https://github.com/graphql-python/graphene/wiki/v3-release-notes
What's Changed
- Graphene v3 following v3 graphql-core by @mvanlonden in #1048
- Fix typos by @minho42 in #1066
- Remove AbstractType by @jkimbo in #1053
- Propagate arguments of relay.NodeField to Field by @tdiam in #1036
- Fix typo in execute.rst by @TheMelter in #1115
- Increase the allowed version of aniso8601 by @ymoch in #1072
- Update quickstart.rst by @ibhlool7 in #1090
- Add file uploading docs by @jkimbo in #1084
- Fix objecttypes DefaultResolver example (#1087) by @tompao in #1088
- Fix tests by @jkimbo in #1119
- Fix example code by @jkimbo in #1120
- Update readme by @jkimbo in #1130
- Use unidecode to handle unicode characters in constant names by @henrythor in #1080
- The default_value of InputField should be INVALID by @ganwell in #1111
- Add a helpful message to when a global_id fails to parse. by @allen-munsch in #1074
- fix example middleware class in docs by @dsanders11 in #1134
- fix typo in class 'Interface' by @JMmmmuu in #1135
- Fix example query in quickstart doc by @ko-lem in #1139
- Fixed import causing Graphene v3 to crash by @jaydenwindle in #1143
- Replace INVALID with Undefined by @jkimbo in #1146
- Added support for subscription by @rob-blackbourn in #1107
- Remove subclass polyfill by @syrusakbary in #1156
- Updated all str.format(…) to f-strings by @syrusakbary in #1158
- Fixed examples, make root object explicit inside resolvers and mutate by @hzlmn in #1159
- Remove unused function by @jkimbo in #1160
- Add some more tests for Interface by @jkimbo in #1154
- Use default_resolver to resolve values when using the source attribute by @jkimbo in #1155
- Add note about the use of
args
by @jkimbo in #1170 - Docs: integrations: fix FastAPI link by @sduthil in #1177
- Fix resolve method parameters bullet list by @rrueth in #1178
- Allow fast ObjectType creation based on dataclasses by @syrusakbary in #1157
- added graphene import to READMEs by @kimbo in #1183
- Update excluded packages list to properly exclude examples package by @radekwlsk in #1187
- Fix typos by @kevinharvey in #1192
- Fix issue with trailing whitespace by @jkimbo in #1197
- Fix typo in quickstart document by @dbgb in #1201
- Fix DateTime Scalar parse_literal methods (#1199) by @Cito in #1200
- Remove @staticmethod decorator in mutations doc by @jkimbo in #1206
- Remove to_const function by @jkimbo in #1212
- Update requirement for Query type in mutation docs by @jkimbo in #1213
- Rename variables called type to type_ by @DoctorJohn in #1216
- Set min version of graphql-core to v3.1.1 by @jkimbo in #1215
- Revert 1213 update mutation docs by @jkimbo in #1214
- ObjectType meta arguments by @jkimbo in #1219
- Add Base64 scalar by @EpicEric in #1221
- Expose Base64 type and add custom scalar examples by @jkimbo in #1223
- Improve enum compatibility by @jkimbo in #1153
- Minor grammatical fix in the schema docs by @rednafi in #1237
- Subscription revamp by @syrusakbary in #1235
- Split out the subscriptions documentation a separate file and fix it by @jkimbo in #1245
- Fix subscribe with arguments by @jkimbo in #1251
- Fix Typo in Docs by @plopd in #1252
- Fix typo in Schema docs by @varundey in #1259
- add BigInt type by @pizzapanther in #1261
- Syntax Error Fixed for Dictionary assert by @lnxpy in #1267
- Add UnforgivingExecutionContext by @AlecRosenbaum in #1255
- Remove Object Mutation dead link from Relay docs by @varundey in #1272
- fix(Decimal): parse integers as decimal. by @zbyte64 in #1295
- Fix links to Relay docs by @bartenra in #1318
- Language fixes on index.rst by @shukryzablah in #1313
- Use argument's
default_value
regardless if the input field is required by @minhtule in #1326 - fix field name in execute.rst example by @kevinr-electric in #1327
- Fix typo in docstring of ObjectType by @sir-sigurd in #1343
- Allow later aniso8601 releases by @fabaff in #1331
- Update pytz to 2021.1 by @fabaff in #1330
- add support for query validation by @aryaniyaps in #1357
- Fix actions by @aryaniyaps in #1359
- Fix GraphQL-core dependency by @ekampf in #1377
- Fix unseen examples by @aryaniyaps in #1376
New Contributors
- @minho42 made their first contribution in #1066
- @tdiam made their first contribution in #1036
- @TheMelter made their first contribution in #1115
- @ymoch made their first contribution in #1072
- @ibhlool7 made their first contribution in #1090
- @tompao made their first contribution in #1088
- @henrythor made their first contribution in #1080
- @ganwell made their first contribution in #1111
- @allen-munsch made their first contribution in #1074
- @dsanders11 made their first contribution in #1134
- @JMmmmuu made their first contribution in #1135
- @ko-lem made their first contribution in #1139
- @jaydenwindle made their first contribution in #1143
- @rob-blackbourn made their first contribution in #1107
- @hzlmn made their first contribution in #1159
- @sduthil made their first contribution in #1177
- @rrueth made their first contribution in #1178
- @kimbo made their first contribution in #1183
- @radekwlsk made their first contribution in #1187
- @kevinharvey made their first contribution in #1192
- @dbgb made their first contribution in #1201
- @Cito made their first contribution in #1200
- @DoctorJohn made their first contribution in #1216
- @EpicEric made their first contribution in https://github.com/graphql-python/graphene...