Skip to content

Commit

Permalink
Merge pull request #106 from evo-company/fix-federation-compat-test
Browse files Browse the repository at this point in the history
fix examples and federation compatibility
  • Loading branch information
kindermax committed Jun 11, 2023
2 parents 01383cd + 11207ff commit 99303bb
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ RUN python3 -m pip install tox tox-pdm

FROM base as examples

RUN pdm sync -G examples
RUN pdm sync -d -G dev -G examples
3 changes: 2 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ services:
- ./scripts:/work/scripts
- ./.flake8:/work/.flake8
- ./pyproject.toml:/work/pyproject.toml
- ./pdm.lock:/work/pdm.lock
init: true
environment:
PYTHONPATH: .
Expand Down Expand Up @@ -55,7 +56,7 @@ services:

federation-compatibility-server:
<<: *examples-base
entrypoint: python3 examples/federation-compatibility/server.py
entrypoint: pdm run python examples/federation-compatibility/server.py

test-base: &test-base
<<: *base
Expand Down
20 changes: 15 additions & 5 deletions examples/federation-compatibility/federation.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ FROM python:3.7.13-slim as base

WORKDIR /work

COPY requirements.txt .
ENV PIP_VERSION=23.1.2
ENV PDM_VERSION=2.6
ENV PDM_USE_VENV=no
ENV PYTHONPATH=/work/__pypackages__/3.7/lib

RUN python3 -m pip install \
--no-deps --no-cache-dir --disable-pip-version-check \
-r requirements.txt
RUN apt-get update && apt-get install -y libpq-dev && \
pip install --upgrade pip==${PIP_VERSION} && pip install pdm==${PDM_VERSION}

RUN python3 -m pip install flask==2.1.3 aiohttp==3.8.1
# for pyproject.toml to extract version
COPY hiku/__init__.py ./hiku/__init__.py
# for pyproject.toml to read readme
COPY README.rst .

COPY pyproject.toml .
COPY pdm.lock .

RUN pdm sync -G dev -G examples

COPY examples/federation-compatibility/server.py .

Expand Down
42 changes: 31 additions & 11 deletions examples/federation-compatibility/server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import sys
import typing as t
from pathlib import Path

from flask import Flask, request, jsonify

Expand All @@ -21,14 +22,14 @@
)
from hiku.federation.endpoint import FederatedGraphQLEndpoint
from hiku.federation.engine import Engine
from hiku.federation.graph import Graph, FederatedNode
from hiku.graph import (
Nothing,
Root,
Field,
Option,
Node,
Link,
Graph,
)
from hiku.readers.graphql import setup_query_cache
from hiku.types import (
Expand All @@ -42,7 +43,7 @@
Sequence,
)
from hiku.executors.sync import SyncExecutor
from hiku.utils import ImmutableDict, listify
from hiku.utils import ImmutableDict, listify, to_immutable_dict

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -162,10 +163,11 @@ def get_field(field: Field, product: dict):

for product_id in ids:
if isinstance(product_id, ImmutableDict):
log.info("product_id %s", product_id)
sku = product_id["sku"]
for product in products:
if product["sku"] == sku:
if product_id.get("id") == product["id"]:
data = product
break
if product_id.get("sku") == product["sku"]:
if "package" in product_id:
if product["package"] == product_id["package"]:
data = product
Expand Down Expand Up @@ -351,6 +353,17 @@ def link_inventory_products(ids):
]


def resolve_reference_by(key):
def resolver(representations):
return [r[key] for r in representations]

return resolver


def resolve_reference_direct(representations):
return [to_immutable_dict(r) for r in representations]


@schema_directive(
name="custom",
locations=[Location.OBJECT],
Expand All @@ -363,7 +376,7 @@ class Custom(FederationSchemaDirective):

QUERY_GRAPH = Graph(
[
Node(
FederatedNode(
"User",
[
Field(
Expand Down Expand Up @@ -397,8 +410,9 @@ class Custom(FederationSchemaDirective):
),
],
directives=[Key("email"), Extends()],
resolve_reference=resolve_reference_by('email')
),
Node(
FederatedNode(
"Product",
[
Field("id", ID, product_fields_resolver),
Expand Down Expand Up @@ -442,6 +456,7 @@ class Custom(FederationSchemaDirective):
Key("sku package"),
Key("sku variation { id }"),
],
resolve_reference=resolve_reference_direct
),
Node(
"ProductDimension",
Expand All @@ -461,7 +476,7 @@ class Custom(FederationSchemaDirective):
],
directives=[Shareable()],
),
Node(
FederatedNode(
"ProductResearch",
[
Field(
Expand All @@ -476,8 +491,9 @@ class Custom(FederationSchemaDirective):
),
],
directives=[Key("study { caseNumber }")],
resolve_reference=resolve_reference_direct
),
Node(
FederatedNode(
"DeprecatedProduct",
[
Field("sku", String, deprecated_product_fields_resolver),
Expand All @@ -500,8 +516,9 @@ class Custom(FederationSchemaDirective):
),
],
directives=[Key("sku package")],
resolve_reference=resolve_reference_direct,
),
Node(
FederatedNode(
"Inventory",
[
Field("id", ID, inventory_fields_resolver),
Expand All @@ -513,6 +530,7 @@ class Custom(FederationSchemaDirective):
),
],
directives=[InterfaceObject(), Key("id")],
resolve_reference=resolve_reference_by("id"),
),
Root(
[
Expand Down Expand Up @@ -576,8 +594,10 @@ def main():
def dump():
from hiku.federation.sdl import print_sdl

out_file = Path(__file__).resolve().parent / 'products.graphql'
print(f"Dumping schema to {out_file}")
sdl = print_sdl(QUERY_GRAPH)
with open("products.graphql", "w") as f:
with open(out_file, "w") as f:
f.write(sdl)


Expand Down
61 changes: 34 additions & 27 deletions examples/graphql_federation_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@

from flask import Flask, request, jsonify

from hiku.federation.directive import (
Extends,
Key,
External,
)
from hiku.federation.directive import Key
from hiku.federation.endpoint import FederatedGraphQLEndpoint
from hiku.federation.engine import Engine
from hiku.federation.graph import Graph, FederatedNode
from hiku.graph import (
Root,
Field,
Option,
Node,
Link,
Graph,
)
from hiku.readers.graphql import setup_query_cache
from hiku.types import (
Expand Down Expand Up @@ -90,30 +85,42 @@ def direct_link(ids):
return ids


"""Example of `cart` subgraph.
def resolve_cart_reference(representations):
return [r['id'] for r in representations]


def resolve_cart_item_reference(representations):
return [r['id'] for r in representations]

`cart` subgraph has `Cart` and `CartItem` types
`order` subgraph has `Order` type

This `cart` subgraph extends `order`'s subgraph type `Order` with `cart` field
"""
Example of `cart` subgraph.
`cart` subgraph has `Cart` and `CartItem` types which can be referenced
from other subgraphs.
"""
QUERY_GRAPH = Graph([
Node('Order', [
Field('cartId', Integer, ids_resolver,
directives=[External()]),
Link('cart', TypeRef['Cart'], direct_link, requires='cartId'),
], directives=[Key('cartId'), Extends()]),
Node('Cart', [
Field('id', Integer, cart_resolver),
Field('status', String, cart_resolver),
Link('items', Sequence[TypeRef['CartItem']], link_cart_items,
requires='id')
], directives=[Key('id')]),
Node('CartItem', [
Field('id', Integer, cart_item_resolver),
Field('cart_id', Integer, cart_item_resolver),
Field('name', String, cart_item_resolver),
]),
FederatedNode(
'Cart',
[
Field('id', Integer, cart_resolver),
Field('status', String, cart_resolver),
Link('items', Sequence[TypeRef['CartItem']], link_cart_items,
requires='id')
],
directives=[Key('id')],
resolve_reference=resolve_cart_reference
),
FederatedNode(
'CartItem',
[
Field('id', Integer, cart_item_resolver),
Field('cart_id', Integer, cart_item_resolver),
Field('name', String, cart_item_resolver),
],
directives=[Key('id')],
resolve_reference=resolve_cart_item_reference
),
Root([
Link(
'cart',
Expand Down
12 changes: 12 additions & 0 deletions hiku/federation/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ def entities_resolver(options: t.Dict) -> t.Tuple[t.List, str]:

typ = representations[0]["__typename"]

if typ not in self.type_to_resolve_reference_map:
raise TypeError(
'Type "{}" must have "reference_resolver"'.format(typ)
)

resolve_reference = self.type_to_resolve_reference_map[typ]
return resolve_reference(representations), typ

Expand All @@ -75,6 +80,13 @@ async def entities_resolver_async(

typ = representations[0]["__typename"]

if typ not in self.type_to_resolve_reference_map:
raise TypeError(
'Type "{}" must have "resolve_reference" function'.format(
typ
)
)

resolve_reference = self.type_to_resolve_reference_map[typ]
coro = resolve_reference(representations)
if isawaitable(coro):
Expand Down
1 change: 1 addition & 0 deletions hiku/federation/sdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ def skip(node: Node) -> bool:
[self.visit(node) for node in obj.items if not skip(node)],
obj.data_types,
obj.directives,
obj.unions,
)

def visit_node(self, obj: Node) -> Node:
Expand Down
3 changes: 2 additions & 1 deletion hiku/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ def __init__(
self.directives: t.Tuple[t.Type[SchemaDirective], ...] = tuple(
directives or ()
)
self.unions: t.Tuple[t.Type[Union], ...] = tuple(unions or ())
self.unions: t.Tuple[t.Type[Union], ...] = unions

def __repr__(self) -> str:
return "{}({!r})".format(self.__class__.__name__, self.items)
Expand Down Expand Up @@ -725,6 +725,7 @@ def visit_graph(self, obj: Graph) -> Graph:
[self.visit(node) for node in obj.items],
obj.data_types,
obj.directives,
obj.unions,
)


Expand Down
3 changes: 1 addition & 2 deletions lets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ commands:
description: Run federation compatibility test
depends: [_build-examples]
cmd: |
echo "Dumping schema..."
docker-compose run --rm federation-compatibility-server dump
mv products.graphql examples/federation-compatibility/products.graphql
export APOLLO_ELV2_LICENSE=accept
npx @apollo/federation-subgraph-compatibility docker \
Expand Down

0 comments on commit 99303bb

Please sign in to comment.