Set of scripts and helper utilities to extend Ariadne GraphQL library
pip install ariadne-extensions
Support for Federation Specification
_Any
, _FieldSet
, ...){_service{sdl}}
query_Entities
union{_entities}
query (resolve_reference
and resolve_references
decorators)ariadne_extensions.federation.FederatedManager
FederatedManager
is a class responsible for creating and executable schema that complies with Federation Specification. Similar to what make_executable_schema
does with ordinary schema file.
Create a FederatedManager instance passing in path to your schema file and QueryType instance. Manager needs to query_type to register _entities
and _service
resolvers.
python
query_type = QueryType()
manager = federation.FederatedManager(
schema_sdl_file='/some/path/schema.graphql',
query=query_type,
)
Register any other ObjectType
s and resolvers by either calling and add_types
method, or by extending manager.types
list.
``` python photo_type = ObjectType('Photo') thumbnail_type = ObjectType('Thumbnail')
manager.add_types(photo_type, thumbnail_type) manager.types.append(snake_case_fallback_resolvers) ```
Finally, get a combiled schema. This compiled schema will extend types defined in '/some/path/schema.graphql' with directives, types and queries, that required by Federation Specification protocol.
python
schema = manager.get_schema()
ariadne_extensions.federation.FederatedObjectType
If you are using GraphQL Federation, your service schema probably implements some so called "boundary objects". That's where FederatedObjectType
is useful.
FederatedObjectType
implements resolve_reference
and resolve_references
decorator. Those are used to register functions, that will be called when a federation gateway calls {_entities{}}
query.
Let's say User
is a boundary type, with a single id
key. You need to implement a function, that will accept a dictionary of keys ({'id': ...} in our example
) and return a User
instance.
FederatedManager will call this function for every _entities([{__typename: 'User', id: ...}])
query.
``` python user_type = federation.FederatedObjectType('User')
@user_type.resolve_reference def resolve_user_reference(representation, obj, info): user_id = representation.get('id') return get_user_by_id(user_id) ```
FederatedObjectType
extends Ariadne's ObjectType
. You can still use the field
decorator, set_alias
method and others as in regular ObjectType
, and others.
python
@user_type.field('name')
def resolve_billing_account(obj, *_, id):
return f'{obj.first_name} {obj_last_name}'
Don't forget to add user_type
to our manager.
python
manager.add_types(user_type)
``` type User @key(fields: "id") @extends { id: ID! @external photos: [Photo]! }
type Photo { id: ID! url: String! description: String } ```
``` python from os.path import dirname, join from ariadne import QueryType, ObjectType, snake_case_fallback_resolvers
from ariadne_extensions import federation
query_type = QueryType() manager = federation.FederatedManager( schema_sdl_file=join(dirname(file), 'schema.graphql'), query=query_type, )
user_type = federation.FederatedObjectType('User') photo_type = ObjectType('Photo')
@user_type.resolve_reference def resolve_user_reference(representation, obj, info): user_id = representation.get('id') return get_user_by_id(user_id)
@user_type.field('name') def resolve_billing_account(obj, *_, id): return f'{obj.first_name} {obj_last_name}'
manager.add_types(user_type, photo_type) manager.add_types(snake_case_fallback_resolvers)
schema = manager.get_schema()
```
Bumps certifi from 2020.12.5 to 2022.12.7.
9e9e840
2022.12.07b81bdb2
2022.09.24939a28f
2022.09.14aca828a
2022.06.15.2de0eae1
Only use importlib.resources's new files() / Traversable API on Python ≥3.11 ...b8eb5e9
2022.06.15.147fb7ab
Fix deprecation warning on Python 3.11 (#199)b0b48e0
fixes #198 -- update link in license9d514b4
2022.06.154151e88
Add py.typed to MANIFEST.in to package in sdist (#196)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps ipython from 7.21.0 to 7.31.1.
e321e76
release 7.31.167ca2b3
Merge pull request from GHSA-pq7m-3gw7-gq5x2794330
back to devbe343e7
release 7.31.00fcf2c4
Merge pull request #13428 from meeseeksmachine/auto-backport-of-pr-13427-on-7.xb8db9b1
Backport PR #13427: wn 7317f253dc
Merge pull request #13412 from bnavigator/backport-inspect4f26796
fix xxlimited_35 import name77ca4a6
don't run nose-based iptest on py310, only pytest533e509
back to decorator skipDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
Bumps urllib3 from 1.26.4 to 1.26.5.
Sourced from urllib3's releases.
1.26.5
:warning: IMPORTANT: urllib3 v2.0 will drop support for Python 2: Read more in the v2.0 Roadmap
- Fixed deprecation warnings emitted in Python 3.10.
- Updated vendored
six
library to 1.16.0.- Improved performance of URL parser when splitting the authority component.
If you or your organization rely on urllib3 consider supporting us via GitHub Sponsors
Sourced from urllib3's changelog.
1.26.5 (2021-05-26)
- Fixed deprecation warnings emitted in Python 3.10.
- Updated vendored
six
library to 1.16.0.- Improved performance of URL parser when splitting the authority component.
d161647
Release 1.26.52d4a3fe
Improve performance of sub-authority splitting in URL2698537
Update vendored six to 1.16.007bed79
Fix deprecation warnings for Python 3.10 ssl moduled725a9b
Add Python 3.10 to GitHub Actions339ad34
Use pytest==6.2.4 on Python 3.10+f271c9c
Apply latest Black formatting1884878
[1.26] Properly proxy EOF on the SSLTransport test suiteDependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
While implementing Ariadne with Federation on top of my Flask Sqlalchemy app I have found an issue having my PublicUserNode
shared with other services on my apollo federation setup. I kept getting this error:
Abstract type _Entity must resolve to an Object type at runtime for field Query._entities with value <User instance>, received 'None'. Either the _Entity type should provide a "resolve_type" function or each possible type should provide an "is_type_of" function.
The reason why I was getting it its because FederationManager._entity_type_resolver was looking for the type name either on the class name, which would not work in my case since my model class name is User
and not PublicUserNode
, or an AriadneMeta
property which is undocumented.
My problem was solved by injecting AriadneMeta
property into my model instance inside the federation object type's resolve_reference
method, but I had to go through the source code to figure out what was missing.
I'd like to suggest to add it to the documentation and create a way to declare the type to be resolved, specially if you have multiple types to represent the same data class.