graphene-federation3


Namegraphene-federation3 JSON
Version 0.3.3.1687272414 PyPI version JSON
download
home_pagehttps://gitlab.com/live-art-project/graphene-federation3
SummaryFederation implementation for graphene3
upload_time2023-06-20 14:46:56
maintainer
docs_urlNone
authorYorsh Siarhei
requires_python
licenseMIT
keywords graphene gql federation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # graphene-federation3
Federation support for graphene


Federation specs implementation on top of Python graphene lib 
https://www.apollographql.com/docs/apollo-server/federation/federation-spec/

Based on discussion: https://github.com/graphql-python/graphene/issues/953#issuecomment-508481652

Supports now:
* sdl (_service fields)  # make possible to add schema in federation (as is)
* `@key` decorator (entity support) # to perform Queries across service boundaries
    *  You can use multiple `@key` per each ObjectType
    ```python
        @key('id')
        @key('email')
        class User(ObjectType):
            id = Int(required=True)
            email = String()
        
            def __resolve_reference(self, info, **kwargs):
                if self.id is not None:
                    return User(id=self.id, email=f'name_{self.id}@gmail.com')
                return User(id=123, email=self.email)              
    ```
* extend  # extend remote types
* external  # mark field as external 
* requires  # mark that field resolver requires other fields to be pre-fetched
* provides # 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 `@provides`** as well as field on a base type that provides. Check example bellow:
    ```python
        import graphene
        from graphene_federation3 import provides
        
        @provides
        class ArticleThatProvideAuthorAge(graphene.ObjectType):
            id = Int(required=True)
            text = String(required=True)
            author = provides(Field(User), fields='age')
    ```

```python
import graphene
from graphene_federation3 import build_schema, key


@key(
    fields='id')  # mark File as Entity and add in EntityUnion https://www.apollographql.com/docs/apollo-server/federation/federation-spec/#key
class File(graphene.ObjectType):
    id = graphene.Int(required=True)
    name = graphene.String()

    def resolve_id(self, info, **kwargs):
        return 1

    def resolve_name(self, info, **kwargs):
        return self.name

    def __resolve_reference(self, info,
                            **kwargs):  # https://www.apollographql.com/docs/apollo-server/api/apollo-federation/#__resolvereference
        return get_file_by_id(self.id)
```

```python
import graphene
from graphene_federation3 import build_schema


class Query(graphene.ObjectType):
    ...
    pass


schema = build_schema(Query)  # add _service{sdl} field in Query
```

```python
import graphene
from graphene_federation3 import external, extend


@extend(fields='id')
class Message(graphene.ObjectType):
    id = external(graphene.Int(required=True))

    def resolve_id(self, **kwargs):
        return 1

```

### __resolve_reference
* Each type which is decorated with `@key` or `@extend` is added to `_Entity` union
* `__resolve_reference` method 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, see [`entity.get_entity_query`](graphene_federation3/entity.py) for more details
* You should define `__resolve_reference`, if you need to extract object before passing it to fields resolvers (example: [FileNode](integration_tests/service_b/schema.py))
* You should not define `__resolve_reference`, if fileds resolvers need only data passed in fieldset (example: [FunnyText](integration_tests/service_a/schema.py))
* read more in [official documentation](https://www.apollographql.com/docs/apollo-server/api/apollo-federation/#__resolvereference)
------------------------


### Known issues:
1. decorators will not work properly
* on fields with capitalised letters with `auto_camelcase=True`, for example: `my_ABC_field = String()`
* on fields with custom names for example `some_field = String(name='another_name')`

---------------------------

For more details see [examples](examples/)

Or better check [integration_tests](integration_tests/)

Also cool [example](https://github.com/preply/graphene-federation/issues/1) of integration with Mongoengine


### For contribution:
#### Run tests:
* `make test`
* if you've changed Dockerfile or requirements run `make build` before `make test`

---------------------------

Also, you can read about how we've come to federation at Preply [here](https://medium.com/preply-engineering/apollo-federation-support-in-graphene-761a0512456d) 

            

Raw data

            {
    "_id": null,
    "home_page": "https://gitlab.com/live-art-project/graphene-federation3",
    "name": "graphene-federation3",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "graphene,gql,federation",
    "author": "Yorsh Siarhei",
    "author_email": "myrik260138@gmail.com",
    "download_url": "",
    "platform": null,
    "description": "# graphene-federation3\nFederation support for graphene\n\n\nFederation specs implementation on top of Python graphene lib \nhttps://www.apollographql.com/docs/apollo-server/federation/federation-spec/\n\nBased on discussion: https://github.com/graphql-python/graphene/issues/953#issuecomment-508481652\n\nSupports now:\n* sdl (_service fields)  # make possible to add schema in federation (as is)\n* `@key` decorator (entity support) # to perform Queries across service boundaries\n    *  You can use multiple `@key` per each ObjectType\n    ```python\n        @key('id')\n        @key('email')\n        class User(ObjectType):\n            id = Int(required=True)\n            email = String()\n        \n            def __resolve_reference(self, info, **kwargs):\n                if self.id is not None:\n                    return User(id=self.id, email=f'name_{self.id}@gmail.com')\n                return User(id=123, email=self.email)              \n    ```\n* extend  # extend remote types\n* external  # mark field as external \n* requires  # mark that field resolver requires other fields to be pre-fetched\n* provides # to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. \n    * **Base class should be decorated with `@provides`** as well as field on a base type that provides. Check example bellow:\n    ```python\n        import graphene\n        from graphene_federation3 import provides\n        \n        @provides\n        class ArticleThatProvideAuthorAge(graphene.ObjectType):\n            id = Int(required=True)\n            text = String(required=True)\n            author = provides(Field(User), fields='age')\n    ```\n\n```python\nimport graphene\nfrom graphene_federation3 import build_schema, key\n\n\n@key(\n    fields='id')  # mark File as Entity and add in EntityUnion https://www.apollographql.com/docs/apollo-server/federation/federation-spec/#key\nclass File(graphene.ObjectType):\n    id = graphene.Int(required=True)\n    name = graphene.String()\n\n    def resolve_id(self, info, **kwargs):\n        return 1\n\n    def resolve_name(self, info, **kwargs):\n        return self.name\n\n    def __resolve_reference(self, info,\n                            **kwargs):  # https://www.apollographql.com/docs/apollo-server/api/apollo-federation/#__resolvereference\n        return get_file_by_id(self.id)\n```\n\n```python\nimport graphene\nfrom graphene_federation3 import build_schema\n\n\nclass Query(graphene.ObjectType):\n    ...\n    pass\n\n\nschema = build_schema(Query)  # add _service{sdl} field in Query\n```\n\n```python\nimport graphene\nfrom graphene_federation3 import external, extend\n\n\n@extend(fields='id')\nclass Message(graphene.ObjectType):\n    id = external(graphene.Int(required=True))\n\n    def resolve_id(self, **kwargs):\n        return 1\n\n```\n\n### __resolve_reference\n* Each type which is decorated with `@key` or `@extend` is added to `_Entity` union\n* `__resolve_reference` method 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.\nIf not explicitly defined, default resolver is used. Default resolver just creates instance of type with passed fieldset as kwargs, see [`entity.get_entity_query`](graphene_federation3/entity.py) for more details\n* You should define `__resolve_reference`, if you need to extract object before passing it to fields resolvers (example: [FileNode](integration_tests/service_b/schema.py))\n* You should not define `__resolve_reference`, if fileds resolvers need only data passed in fieldset (example: [FunnyText](integration_tests/service_a/schema.py))\n* read more in [official documentation](https://www.apollographql.com/docs/apollo-server/api/apollo-federation/#__resolvereference)\n------------------------\n\n\n### Known issues:\n1. decorators will not work properly\n* on fields with capitalised letters with `auto_camelcase=True`, for example: `my_ABC_field = String()`\n* on fields with custom names for example `some_field = String(name='another_name')`\n\n---------------------------\n\nFor more details see [examples](examples/)\n\nOr better check [integration_tests](integration_tests/)\n\nAlso cool [example](https://github.com/preply/graphene-federation/issues/1) of integration with Mongoengine\n\n\n### For contribution:\n#### Run tests:\n* `make test`\n* if you've changed Dockerfile or requirements run `make build` before `make test`\n\n---------------------------\n\nAlso, you can read about how we've come to federation at Preply [here](https://medium.com/preply-engineering/apollo-federation-support-in-graphene-761a0512456d) \n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Federation implementation for graphene3",
    "version": "0.3.3.1687272414",
    "project_urls": {
        "Homepage": "https://gitlab.com/live-art-project/graphene-federation3"
    },
    "split_keywords": [
        "graphene",
        "gql",
        "federation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7cc9116744ed7f47944701252838f748b3589c897907b424733fd1ac48336a48",
                "md5": "e3931566f55e4fc3c23777c51179c314",
                "sha256": "125dd6a3405123a6c84fcf77949eb3b98d3abb6bf9e897e6a0c109ef89941671"
            },
            "downloads": -1,
            "filename": "graphene_federation3-0.3.3.1687272414-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e3931566f55e4fc3c23777c51179c314",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 13842,
            "upload_time": "2023-06-20T14:46:56",
            "upload_time_iso_8601": "2023-06-20T14:46:56.674712Z",
            "url": "https://files.pythonhosted.org/packages/7c/c9/116744ed7f47944701252838f748b3589c897907b424733fd1ac48336a48/graphene_federation3-0.3.3.1687272414-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-20 14:46:56",
    "github": false,
    "gitlab": true,
    "bitbucket": false,
    "codeberg": false,
    "gitlab_user": "live-art-project",
    "gitlab_project": "graphene-federation3",
    "lcname": "graphene-federation3"
}
        
Elapsed time: 0.08566s