ray[default]==1.8.0
ray[serve]==1.8.0
aiohttp>=3.7, <3.8 # ray has >3.7 but 3.8 breaks it
fastapi==0.70.0
strawberry-graphql==0.90.2
Code:
import ray
import strawberry
from fastapi import FastAPI
from ray import serve
from strawberry.asgi import GraphQL
@strawberry.type
class User:
name: str
age: int
@strawberry.type
class Query:
@strawberry.field
def user(self) -> User:
return User(name="Patrick", age=100)
schema = strawberry.Schema(query=Query)
graphql_app = GraphQL(schema)
app = FastAPI()
app.add_route("/graphql", graphql_app)
ray.init(address="auto", namespace="graphql")
serve.start(detached=True)
@serve.deployment(route_prefix="/")
@serve.ingress(app)
class FastAPIWrapper:
pass
FastAPIWrapper.deploy()
This is throwing me this error when executing:
2021-11-30 17:43:26,556 INFO worker.py:822 -- Connecting to existing Ray cluster at address: 127.0.0.1:6379
2021-11-30 17:43:27,435 INFO checkpoint_path.py:15 -- Using RayInternalKVStore for controller checkpoint and recovery.
2021-11-30 17:43:27,438 INFO http_state.py:98 -- Starting HTTP proxy with name 'SERVE_CONTROLLER_ACTOR:SERVE_PROXY_ACTOR-node:127.0.0.1-0' on node 'node:127.0.0.1-0' listening on '127.0.0.1:8000'
2021-11-30 17:43:28,229 INFO api.py:441 -- Started detached Serve instance in namespace 'graphql'.
Traceback (most recent call last):
File "serve.py", line 34, in <module>
class FastAPIWrapper:
File "/Users/hfernandes/Projects/ray-serve/.venv/lib/python3.8/site-packages/ray/serve/api.py", line 554, in decorator
frozen_app = cloudpickle.loads(cloudpickle.dumps(app))
File "/Users/hfernandes/Projects/ray-serve/.venv/lib/python3.8/site-packages/graphql/pyutils/frozen_list.py", line 48, in extend
raise FrozenError
graphql.pyutils.frozen_error.FrozenError
As a walkaround i think what i found at the bottom of Redirecting... might help that uses starlette-graphene3 instead since we support Starlette in serve app serialization. Do you mind giving it try to it and let us know if you run into more issues ?
I’ve tried with the following snippet for graphene 2.1.9.
import ray
from fastapi import FastAPI
from graphene import ObjectType, Schema, String
from ray import serve
from starlette.graphql import GraphQLApp
class Query(ObjectType):
# this defines a Field `hello` in our Schema with a single Argument `name`
hello = String(name=String(default_value="stranger"))
goodbye = String()
# our Resolver method takes the GraphQL context (root, info) as well as
# Argument (name) for the Field and returns data for the query Response
def resolve_hello(root, info, name):
return f'Hello {name}!'
def resolve_goodbye(root, info):
return 'See ya!'
schema = Schema(query=Query)
graphql_app = GraphQLApp(schema)
app = FastAPI()
app.add_route("/graphql", graphql_app)
ray.init(address="auto", namespace="graphql")
serve.start(detached=True)
@serve.deployment(route_prefix="/")
@serve.ingress(app)
class FastAPIWrapper:
pass
FastAPIWrapper.deploy()
And got the error:
2021-12-02 10:59:32,674 INFO worker.py:822 -- Connecting to existing Ray cluster at address: 127.0.0.1:6379
2021-12-02 10:59:33,599 INFO checkpoint_path.py:15 -- Using RayInternalKVStore for controller checkpoint and recovery.
2021-12-02 10:59:33,603 INFO http_state.py:98 -- Starting HTTP proxy with name 'SERVE_CONTROLLER_ACTOR:SERVE_PROXY_ACTOR-node:127.0.0.1-0' on node 'node:127.0.0.1-0' listening on '127.0.0.1:8000'
INFO: Started server process [49544]
2021-12-02 10:59:34,362 INFO api.py:441 -- Started detached Serve instance in namespace 'graphql'.
Traceback (most recent call last):
File "serve-phene.py", line 35, in <module>
class FastAPIWrapper:
File "/Users/hfernandes/Projects/ray-serve/.venv/lib/python3.8/site-packages/ray/serve/api.py", line 554, in decorator
frozen_app = cloudpickle.loads(cloudpickle.dumps(app))
TypeError: __init__() missing 1 required positional argument: 'types'
Then swapped to graphene 3.0 and starlette-graphene3==0.5.1 and replaced the GraphQLApp import to
from starlette_graphene3 import GraphQLApp
and the error was the same as with Strawberry.
I feel that the problem is with serializing something on the graphql-core library, which both graphene and strawberry depend uppon.
Thanks for trying out on this, I think you’ve uncovered a pattern that other uses might run into as well about serialization. We force serializing fastapi app but it seems like blocking use cases like yours.
The good news is, it’s possible to avoid serializing it to get rid of this class of failure. @simon-mo is working on a one pager for this.