Package: cxa-graphene-federation
graphene-federationFederation support for grapheneBuild:Federation specs implementation on top of Python graphene libhttps://www.apollographql.com/docs/apollo-server/federation/federation-spec/Based on discussion:https://github.com/graphql-python/graphene/issues/953#issuecomment-508481652Supports now:sdl (_service fields)  # make possible to add schema in federation (as is)@keydecorator (entity support) # to perform Queries across service boundariesYou can use multiple@keyper each ObjectType@key('id')@key('email')classUser(ObjectType):id=Int(required=True)email=String()def__resolve_reference(self,info,**kwargs):ifself.idisnotNone:returnUser(id=self.id,email=f'name_{self.id}@gmail.com')returnUser(id=123,email=self.email)extend  # extend remote typesexternal  # mark field as externalrequires  # mark that field resolver requires other fields to be pre-fetchedprovides  # to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway.Base class should be decorated with@providesas well as field on a base type that provides. Check example bellow:importgraphenefromgraphene_federationimportprovides@providesclassArticleThatProvideAuthorAge(graphene.ObjectType):id=Int(required=True)text=String(required=True)author=provides(Field(User),fields='age')importgraphenefromgraphene_federationimportbuild_schema,key@key(fields='id')# mark File as Entity and add in EntityUnion https://www.apollographql.com/docs/apollo-server/federation/federation-spec/#keyclassFile(graphene.ObjectType):id=graphene.Int(required=True)name=graphene.String()defresolve_id(self,info,**kwargs):return1defresolve_name(self,info,**kwargs):returnself.namedef__resolve_reference(self,info,**kwargs):# https://www.apollographql.com/docs/apollo-server/api/apollo-federation/#__resolvereferencereturnget_file_by_id(self.id)importgraphenefromgraphene_federationimportbuild_schemaclassQuery(graphene.ObjectType):...passschema=build_schema(Query)# add _service{sdl} field in Queryimportgraphenefromgraphene_federationimportexternal,extend@extend(fields='id')classMessage(graphene.ObjectType):id=external(graphene.Int(required=True))defresolve_id(self,**kwargs):return1__resolve_referenceEach type which is decorated with@keyor@extendis added to_Entityunion__resolve_referencemethod can be defined for each type that is an entity. This method is called whenever an entity is requested as part of the fulfilling a query plan.
If not explicitly defined, default resolver is used. Default resolver just creates instance of type with passed fieldset as kwargs, seeentity.get_entity_queryfor more detailsYou should define__resolve_reference, if you need to extract object before passing it to fields resolvers (example:FileNode)You should not define__resolve_reference, if fileds resolvers need only data passed in fieldset (example:FunnyText)read more inofficial documentationKnown issues:decorators will not work properlyon fields with capitalised letters withauto_camelcase=True, for example:my_ABC_field = String()on fields with custom names for examplesome_field = String(name='another_name')For more details seeexamplesOr better checkintegration_testsAlso coolexampleof integration with MongoengineFor contribution:Run tests:make testif you've changed Dockerfile or requirements runmake buildbeforemake testAlso, you can read about how we've come to federation at Preplyhere