NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1727 most downloaded on PyPI
A library for creating GraphQL APIs
Last release 21 days ago
07 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
1114 releases · first in 2019
In this release, we pass the default values from the strawberry.Schema through to the codegen plugins. The default python plugin now adds these defaul
In this release, we pass the default values from the strawberry.Schema through to the codegen plugins. The default python plugin now adds these default values to the objects it generates.
Contributed by Matt Gilson via PR #2860
This release removes more parts of the Mypy plugin, since they are not needed anymore.
This release removes more parts of the Mypy plugin, since they are not needed anymore.
Contributed by Patrick Arminio via PR #2852
One column per quarter.
This release fixes a bug causing a KeyError exception to be thrown during subscription cleanup.
Nothing published for this version
Correct a type-hinting bug with strawberry.directive. This may cause some consumers to have to remove a # type: ignore comment or unnecessary typing.c
Correct a type-hinting bug with strawberry.directive.
This may cause some consumers to have to remove a # type: ignore comment
or unnecessary typing.cast in order to get mypy to pass.
Contributed by Matt Gilson via PR #2847
This release removes our custom __dataclass_transform__ decorator and replaces it with typing-extension's one. It also removes parts of the mypy plugi
This release removes our custom __dataclass_transform__ decorator and replaces
it with typing-extension's one. It also removes parts of the mypy plugin, since
most of it is not needed anymore 🙌
This update requires typing_extensions>=4.1.0
Contributed by Patrick Arminio via PR #2227
This release migrates our CLI to typer, all commands should work the same as before.
This release migrates our CLI to typer, all commands should work the same as before.
Contributed by Patrick Arminio via PR #2569
This release improves the relay.NodeID annotation check by delaying it until after class initialization. This resolves issues with evaluating type an
This release improves the relay.NodeID annotation check by delaying it until after class initialization. This resolves issues with evaluating type annotations before they are fully defined and enables integrations to inject code for it in the type.
Contributed by Thiago Bellini Ribeiro via PR #2838
This release fixes a bug in the codegen where List objects are currently emitted as Optional objects.
This release fixes a bug in the codegen where List objects are currently emitted
as Optional objects.
Contributed by Matt Gilson via PR #2843
Refactor ConnectionExtension to copy arguments instead of extending them. This should fix some issues with integrations which override arguments, like
Refactor ConnectionExtension to copy arguments instead of extending them.
This should fix some issues with integrations which override arguments,
like the django one, where the inserted arguments were vanishing.
Contributed by Thiago Bellini Ribeiro via PR #2839
This release fixes a bug where codegen would fail on mutations that have object arguments in the query.
This release fixes a bug where codegen would fail on mutations that have object arguments in the query.
Additionally, it does a topological sort of the types before passing it to the plugins to ensure that dependent types are defined after their dependencies.
Contributed by Matt Gilson via PR #2831
This release fixes an issue where Strawberry would make copies of types that were using specialized generics that were not Strawerry types.
This release fixes an issue where Strawberry would make copies of types that were using specialized generics that were not Strawerry types.
This issue combined with the use of lazy types was resulting in duplicated type errors.
Contributed by Patrick Arminio via PR #2824
This release fixes an issue for parsing lazy types using forward references when they were enclosed in an Optional[...] type.
This release fixes an issue for parsing lazy types using forward references
when they were enclosed in an Optional[...] type.
The following now should work properly:
from __future__ import annotations
from typing import Optional, Annotated
import strawberry
@strawberry.type
class MyType:
other_type: Optional[Annotated["OtherType", strawberry.lazy("some.module")]]
# or like this
other_type: Annotated["OtherType", strawberry.lazy("some.module")] | None
Contributed by Thiago Bellini Ribeiro via PR #2821
This release fixes a codegen bug. Prior to this fix, inline fragments would only include the last field defined within its scope and all fields common
This release fixes a codegen bug. Prior to this fix, inline fragments would only include the last field defined within its scope and all fields common with its siblings.
After this fix, all fields will be included in the generated types.
Contributed by Matt Gilson via PR #2819
Fields with generics support directives.
This release fixes an issue of the new relay integration adding an id: GlobalID! argument on all objects that inherit from relay.Node. That should've
This release fixes an issue of the new relay integration adding an id: GlobalID!
argument on all objects that inherit from relay.Node. That should've only happened
for Query types.
Strawberry now will not force a relay.Node or any type that inherits it to be
inject the node extension which adds the argument and a resolver for it, meaning that
this code:
import strawberry
from strawberry import relay
@strawberry.type
class Fruit(relay.Node):
id: relay.NodeID[int]
@strawberry.type
class Query:
node: relay.Node
fruit: Fruit
Should now be written as:
import strawberry
from strawberry import relay
@strawberry.type
class Fruit(relay.Node):
id: relay.NodeID[int]
@strawberry.type
class Query:
node: relay.Node = relay.node() # <- note the "= relay.node()" here
fruit: Fruit = relay.node()
Contributed by Thiago Bellini Ribeiro via PR #2814
Nothing published for this version
This release adds a new field extension called InputMutationExtension, which makes it easier to create mutations that receive a single input type call
This release adds a new field extension called InputMutationExtension, which makes
it easier to create mutations that receive a single input type called input,
while still being able to define the arguments of that input on the resolver itself.
The following example:
import strawberry
from strawberry.field_extensions import InputMutationExtension
@strawberry.type
class Fruit:
id: strawberry.ID
name: str
weight: float
@strawberry.type
class Mutation:
@strawberry.mutation(extensions=[InputMutationExtension()])
def update_fruit_weight(
self,
info: strawberry.Info,
id: strawberry.ID,
weight: Annotated[
float,
strawberry.argument(description="The fruit's new weight in grams"),
],
) -> Fruit:
fruit = ... # retrieve the fruit with the given ID
fruit.weight = weight
... # maybe save the fruit in the database
return fruit
Would generate a schema like this:
input UpdateFruitInput {
id: ID!
"""
The fruit's new weight in grams
"""
weight: Float!
}
type Fruit {
id: ID!
name: String!
weight: Float!
}
type Mutation {
updateFruitWeight(input: UpdateFruitInput!): Fruit!
}
Contributed by Thiago Bellini Ribeiro via PR #2580
Initial relay spec implementation. For information on how to use it, check out the docs in here: https://strawberry.rocks/docs/guides/relay
Initial relay spec implementation. For information on how to use it, check out the docs in here: https://strawberry.rocks/docs/guides/relay
Contributed by Thiago Bellini Ribeiro via PR #2511
Nothing published for this version
This release adds support for properly resolving lazy references when using forward refs.
This release adds support for properly resolving lazy references when using forward refs.
For example, this code should now work without any issues:
from __future__ import annotations
from typing import TYPE_CHECKING, Annotated
if TYPE_CHECKING:
from some.module import OtherType
@strawberry.type
class MyType:
@strawberry.field
async def other_type(
self,
) -> Annotated[OtherType, strawberry.lazy("some.module")]: ...
Contributed by Thiago Bellini Ribeiro via PR #2744
This release fixes a bug in fragment codegen to pick up type definitions from the proper place in the schema.
This release fixes a bug in fragment codegen to pick up type definitions from the proper place in the schema.
Contributed by Matt Gilson via PR #2805
Custom codegen plugins will fail to write files if the plugin is trying to put the file anywhere other than the root output directory (since the child
Custom codegen plugins will fail to write files if the plugin is trying to put the file anywhere other than the root output directory (since the child directories do not yet exist). This change will create the child directory if necessary before attempting to write the file.
Contributed by Matt Gilson via PR #2806
This release updates the built-in GraphiQL to the current latest version 2.4.7 and improves styling for the GraphiQL Explorer Plugin.
In this release codegen no longer chokes on queries that use a fragment.
In this release codegen no longer chokes on queries that use a fragment.
There is one significant limitation at the present. When a fragment is included via the spread operator in an object, it must be the only field present. Attempts to include more fields will result in a ValueError.
However, there are some real benefits. When a fragment is included in multiple places in the query, only a single class will be made to represent that fragment:
fragment Point on Bar {
id
x
y
}
query GetPoints {
circlePoints {
...Point
}
squarePoints {
...Point
}
}
Might generate the following types
class Point:
id: str
x: float
y: float
class GetPointsResult:
circle_points: List[Point]
square_points: List[Point]
The previous behavior would generate duplicate classes for for the GetPointsCirclePoints and GetPointsSquarePoints even though they are really identical classes.
Contributed by Matt Gilson via PR #2802
Make StrawberryAnnotation hashable, to make it compatible to newer versions of dacite.
Make StrawberryAnnotation hashable, to make it compatible to newer versions of dacite.
Contributed by Jaime Coello de Portugal via PR #2790
This release contains a breaking change for the Channels integration. The context object is now a dict and it contains different keys depending on the…
This release updates the Django Channels integration so that it uses the same base classes used by all other integrations.
New features:
The Django Channels integration supports two new features:
multipart/form-data POST requestsBreaking changes:
This release contains a breaking change for the Channels integration. The context
object is now a dict and it contains different keys depending on the connection
protocol:
request and response. The request object contains the full
request (including the body). Previously, request was the GraphQLHTTPConsumer
instance of the current connection. The consumer is now available via
request.consumer.request, ws and response. request and ws are the same
GraphQLWSConsumer instance of the current connection.If you want to use a dataclass for the context object (like in previous releases),
you can still use them by overriding the get_context methods. See the Channels
integration documentation for an example.
Contributed by Christian Dröge via PR #2775
This PR allows passing metadata to Strawberry arguments.
This PR allows passing metadata to Strawberry arguments.
Example:
import strawberry
@strawberry.type
class Query:
@strawberry.field
def hello(
self,
info,
input: Annotated[str, strawberry.argument(metadata={"test": "foo"})],
) -> str:
argument_definition = info.get_argument_definition("input")
assert argument_definition.metadata["test"] == "foo"
return f"Hi {input}"
Contributed by Jonathan Kim via PR #2755
In this release codegen no longer chokes on queries that have a __typename in them. Python generated types will not have the __typename included in th
In this release codegen no longer chokes on queries that have a __typename in them.
Python generated types will not have the __typename included in the fields.
Contributed by Matt Gilson via PR #2797
Prevent AssertionError when using strawberry codegen on a query file that contains a mutation.
Prevent AssertionError when using strawberry codegen on a query file that contains a mutation.
Contributed by Matt Gilson via PR #2795
This release fixes a bug in experimental.pydantic whereby Optional type annotations weren't exactly aligned between strawberry type and pydantic model
This release fixes a bug in experimental.pydantic whereby Optional type annotations weren't exactly aligned between strawberry type and pydantic model.
Previously this would have caused the series field to be non-nullable in graphql.
from typing import Optional
from pydantic import BaseModel, Field
import strawberry
class VehicleModel(BaseModel):
series: Optional[str] = Field(default="")
@strawberry.experimental.pydantic.type(model=VehicleModel, all_fields=True)
class VehicleModelType:
pass
Contributed by Nick Butlin via PR #2782
This release introduces the new should_ignore argument to the QueryDepthLimiter extension that provides a more general and more verbose way of specify
This release introduces the new should_ignore argument to the QueryDepthLimiter extension that provides
a more general and more verbose way of specifying the rules by which a query's depth should be limited.
The should_ignore argument should be a function that accepts a single argument of type IgnoreContext.
The IgnoreContext class has the following attributes:
field_name of type str: the name of the field to be compared againstfield_args of type strawberry.extensions.query_depth_limiter.FieldArgumentsType: the arguments of the field to be compared againstquery of type graphql.language.Node: the query stringcontext of type graphql.validation.ValidationContext: the context passed to the query
and returns True if the field should be ignored and False otherwise.
This argument is injected, regardless of name, by the QueryDepthLimiter class and should not be passed by the user.Instead, the user should write business logic to determine whether a field should be ignored or not by
the attributes of the IgnoreContext class.
For example, the following query:
"""
query {
matt: user(name: "matt") {
email
}
andy: user(name: "andy") {
email
address {
city
}
pets {
name
owner {
name
}
}
}
}
"""
can have its depth limited by the following should_ignore:
from strawberry.extensions import IgnoreContext
def should_ignore(ignore: IgnoreContext):
return ignore.field_args.get("name") == "matt"
query_depth_limiter = QueryDepthLimiter(should_ignore=should_ignore)
so that it effectively becomes:
"""
query {
andy: user(name: "andy") {
email
pets {
name
owner {
name
}
}
}
}
"""
Contributed by Tommy Smith via PR #2505
This release adds a method on the DatadogTracingExtension class called create_span that can be overridden to create a custom span or add additional ta
This release adds a method on the DatadogTracingExtension class called create_span that can be overridden to create a custom span or add additional tags to the span.
from ddtrace import Span
from strawberry.extensions import LifecycleStep
from strawberry.extensions.tracing import DatadogTracingExtension
class DataDogExtension(DatadogTracingExtension):
def create_span(
self,
lifecycle_step: LifecycleStep,
name: str,
**kwargs,
) -> Span:
span = super().create_span(lifecycle_step, name, **kwargs)
if lifecycle_step == LifeCycleStep.OPERATION:
span.set_tag("graphql.query", self.execution_context.query)
return span
Contributed by Ronald Williams via PR #2773
This release fixes an issue with optional scalars using the or notation with forward references on python 3.10.
This release fixes an issue with optional scalars using the or
notation with forward references on python 3.10.
The following code would previously raise TypeError on python 3.10:
from __future__ import annotations
import strawberry
from strawberry.scalars import JSON
@strawberry.type
class SomeType:
an_optional_json: JSON | None
Contributed by Thiago Bellini Ribeiro via PR #2774
This release adds support for using enum_value with IntEnums, like this:
This release adds support for using enum_value with IntEnums, like this:
import strawberry
from enum import IntEnum
@strawberry.enum
class Color(IntEnum):
OTHER = strawberry.enum_value(
-1, description="Other: The color is not red, blue, or green."
)
RED = strawberry.enum_value(0, description="Red: The color red.")
BLUE = strawberry.enum_value(1, description="Blue: The color blue.")
GREEN = strawberry.enum_value(2, description="Green: The color green.")
Contributed by Patrick Arminio via PR #2761
This release adds a SentryTracingExtension that you can use to automatically add tracing information to your GraphQL queries.
This release adds a SentryTracingExtension that you can use to automatically add tracing information to your GraphQL queries.
Contributed by Patrick Arminio via PR #2495
Unfortunately, this release does contain some breaking changes, but they are minimal and should be quick to fix.
This release adds support for custom classes inside the OpenTelemetry integration. With this, we shouldn't see errors like this anymore:
Invalid type dict for attribute 'graphql.param.paginator' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types.
Contributed by Budida Abhinav Ramana via PR #2753
Add get_argument_definition helper function on the Info object to get
a StrawberryArgument definition by argument name from inside a resolver or
Field Extension.
Example:
import strawberry
@strawberry.type
class Query:
@strawberry.field
def field(
self,
info,
my_input: Annotated[
str,
strawberry.argument(description="Some description"),
],
) -> str:
my_input_def = info.get_argument_definition("my_input")
assert my_input_def.type is str
assert my_input_def.description == "Some description"
return my_input
Contributed by Jonathan Kim via PR #2732
This release adds more type hints to internal APIs and public APIs.
Contributed by Alex Auritt via PR #2568
This release improves the graphql-transport-ws implementation by starting the sub-protocol timeout only when the connection handshake is completed.
Contributed by Kristján Valur Jónsson via PR #2703
This release parses the input arguments to a field earlier so that Field Extensions recieve instances of Input types rather than plain dictionaries.
Example:
import strawberry
from strawberry.extensions import FieldExtension
@strawberry.input
class MyInput:
foo: str
class MyFieldExtension(FieldExtension):
def resolve(
self, next_: Callable[..., Any], source: Any, info: strawberry.Info, **kwargs
):
# kwargs["my_input"] is instance of MyInput
...
@strawberry.type
class Query:
@strawberry.field
def field(self, my_input: MyInput) -> str:
return "hi"
Contributed by Jonathan Kim via PR #2731
This release adds a missing parameter to get_context
when using subscriptions with ASGI.
Contributed by Patrick Arminio via PR #2739
Do not display graphiql view in fastapi doc if graphiql parameter is deactivated
Contributed by yak-toto via PR #2736
This PR adds a MaxTokensLimiter extension which limits the number of tokens in a GraphQL document.
import strawberry
from strawberry.extensions import MaxTokensLimiter
schema = strawberry.Schema(
Query,
extensions=[
MaxTokensLimiter(max_token_count=1000),
],
)
Contributed by reka via PR #2729
This release bumps the version of typing_extensions to >= 4.0.0 to fix the
error: "cannot import Self from typing_extensions".
Contributed by Tien Truong via PR #2704
This releases adds an extension for PyInstrument. It allows to instrument your server and find slow code paths.
You can use it like this:
import strawberry
from strawberry.extensions import pyinstrument
schema = strawberry.Schema(
Query,
extensions=[
pyinstrument.PyInstrument(report_path="pyinstrument.html"),
],
)
Contributed by Peyton Duncan via PR #2727
This PR adds a MaxAliasesLimiter extension which limits the number of aliases in a GraphQL document.
import strawberry
from strawberry.extensions import MaxAliasesLimiter
schema = strawberry.Schema(
Query,
extensions=[
MaxAliasesLimiter(max_alias_count=15),
],
)
Contributed by reka via PR #2726
This release adds missing annotations in class methods, improving our type coverage.
Contributed by Kai Benevento via PR #2721
graphql_transport_ws: Cancelling a subscription no longer blocks the connection
while any subscription finalizers run.
Contributed by Kristján Valur Jónsson via PR #2718
This release fix the return value of enums when using a custom name converter for them.
Contributed by Patrick Arminio via PR #2696
This release adds support for Mypy 1.2.0
Contributed by Patrick Arminio via PR #2693
This release add support for converting the enum value names
from NameConverter. It looks like this:
from enum import Enum
import strawberry
from strawberry.enum import EnumDefinition, EnumValue
from strawberry.schema.config import StrawberryConfig
from strawberry.schema.name_converter import NameConverter
class EnumNameConverter(NameConverter):
def from_enum_value(self, enum: EnumDefinition, enum_value: EnumValue) -> str:
return f"{super().from_enum_value(enum, enum_value)}_enum_value"
@strawberry.enum
class MyEnum(Enum):
A = "a"
B = "b"
@strawberry.type
class Query:
a_enum: MyEnum
schema = strawberry.Schema(
query=Query,
config=StrawberryConfig(name_converter=EnumNameConverter()),
)
Contributed by Patrick Arminio via PR #2690
This release updates all* the HTTP integration to use the same base class, which makes it easier to maintain and extend them in future releases.
While this doesn't provide any new features (other than settings headers in Chalice and Sanic), it does make it easier to extend the HTTP integrations in the future. So, expect some new features in the next releases!
New features:
Now both Chalice and Sanic integrations support setting headers in the response. Bringing them to the same level as the other HTTP integrations.
Breaking changes:
Unfortunately, this release does contain some breaking changes, but they are minimal and should be quick to fix.
get_root_value and get_context now receive the requestget_root_value now receives the request and it is async* The only exception is the channels http integration, which will be updated in a future release.
Contributed by Patrick Arminio via PR #2681
Fixes type hint for StrawberryTypeFromPydantic._pydantic_type to be a Type instead of an instance of the Pydantic model. As it is a private API, we still highly discourage using it, but it's now typed correctly.
from pydantic import BaseModel
from typing import Type, List
import strawberry
from strawberry.experimental.pydantic.conversion_types import StrawberryTypeFromPydantic
class User(BaseModel):
name: str
@staticmethod
def foo() -> List[str]:
return ["Patrick", "Pietro", "Pablo"]
@strawberry.experimental.pydantic.type(model=User, all_fields=True)
class UserType:
@strawberry.field
def foo(self: StrawberryTypeFromPydantic[User]) -> List[str]:
# This is now inferred correctly as Type[User] instead of User
# We still highly discourage using this private API, but it's
# now typed correctly
pydantic_type: Type[User] = self._pydantic_type
return pydantic_type.foo()
def get_users() -> UserType:
user: User = User(name="Patrick")
return UserType.from_pydantic(user)
@strawberry.type
class Query:
user: UserType = strawberry.field(resolver=get_users)
schema = strawberry.Schema(query=Query)
Contributed by James Chua via PR #2683
This releases adds a new extra group for Starlite, preventing it from being
installed by default.
Contributed by Patrick Arminio via PR #2664
This release adds support for starlite.
import strawberry
from starlite import Request, Starlite
from strawberry.starlite import make_graphql_controller
from strawberry.types.info import Info
def custom_context_getter(request: Request):
return {"custom": "context"}
@strawberry.type
class Query:
@strawberry.field
def hello(self, info: strawberry.Info[object, None]) -> str:
return info.context["custom"]
schema = strawberry.Schema(Query)
GraphQLController = make_graphql_controller(
schema,
path="/graphql",
context_getter=custom_context_getter,
)
app = Starlite(
route_handlers=[GraphQLController],
)
Contributed by Matthieu MN via PR #2391
This release fixes and issue where you'd get a warning
about using Apollo Federation directives even when using
strawberry.federation.Schema.
Contributed by Patrick Arminio via PR #2661
This releases adds more type annotations for public functions and methods.
No new changes have been added to the API.
Contributed by Jad Haddad via PR #2627
This release adds a warning when using @strawberry.federation.type
but not using strawberry.federation.Schema
Contributed by Rubens O Leão via PR #2572
Updates the MaskErrors extension to the new extension API, which was missed previously.
Contributed by Nikolai Maas via PR #2655
Add full support for forward references, specially when using
from __future__ import annotations.
Before the following would fail on python versions older than 3.10:
from __future__ import annotations
import strawberry
@strawberry.type
class Query:
foo: str | None
Also, this would fail in any python versions:
from __future__ import annotations
from typing import Annotated
import strawberry
@strawberry.type
class Query:
foo: Annotated[str, "some annotation"]
Now both of these cases are supported. Please open an issue if you find any edge cases that are still not supported.
Contributed by Thiago Bellini Ribeiro via PR #2592
Fix interface duplication leading to schema compilation error in multiple inheritance scenarios (i.e. "Diamond Problem" inheritance)
Thank you @mzhu22 for the thorough bug report!
Contributed by San Kilkis via PR #2647
This release introduces a breaking change to make pydantic default behavior consistent with normal strawberry types. This changes the schema generated for pydantic types, that are required, and have default values. Previously pydantic type with a default, would get converted to a strawberry type that is not required. This is now fixed, and the schema will now correctly show the type as required.
import pydantic
import strawberry
class UserPydantic(pydantic.BaseModel):
name: str = "James"
@strawberry.experimental.pydantic.type(UserPydantic, all_fields=True)
class User: ...
@strawberry.type
class Query:
a: User = strawberry.field()
@strawberry.field
def a(self) -> User:
return User()
The schema is now
type Query {
a: User!
}
type User {
name: String! // String! rather than String previously
}
Contributed by James Chua via PR #2623
This release covers an edge case where the following would not give a nice error.
some_field: "Union[list[str], SomeType]]"
Fixes #2591
Contributed by ניר via PR #2593
Provide close reason to ASGI websocket as specified by ASGI 2.3
Contributed by Kristján Valur Jónsson via PR #2639
This release adds support for list arguments in operation directives.
The following is now supported:
@strawberry.directive(locations=[DirectiveLocation.FIELD])
def append_names(
value: DirectiveValue[str], names: List[str]
): # note the usage of List here
return f"{value} {', '.join(names)}"
Contributed by chenyijian via PR #2632
Adds support for a custom field using the approach specified in issue #2168. Field Extensions may be used to change the way how fields work and what they return. Use cases might include pagination, permissions or other behavior modifications.
from strawberry.extensions import FieldExtension
class UpperCaseExtension(FieldExtension):
async def resolve_async(
self,
next: Callable[..., Awaitable[Any]],
source: Any,
info: strawberry.Info,
**kwargs,
):
result = await next(source, info, **kwargs)
return str(result).upper()
@strawberry.type
class Query:
@strawberry.field(extensions=[UpperCaseExtension()])
async def string(self) -> str:
return "This is a test!!"
query {
string
}
{
"string": "THIS IS A TEST!!"
}
Contributed by Erik Wrede via PR #2567
Ensure that no other messages follow a "complete" or "error" message for an operation in the graphql-transport-ws protocol.
Contributed by Kristján Valur Jónsson via PR #2600
Calling ChannelsConsumer.channel_listen multiple times will now pass
along the messages being listened for to multiple callers, rather than
only one of the callers, which was the old behaviour.
This resolves an issue where creating multiple GraphQL subscriptions using a single websocket connection could result in only one of those subscriptions (in a non-deterministic order) being triggered if they are listening for channel layer messages of the same type.
Contributed by James Thorniley via PR #2525
Rename Extension to SchemaExtension to pave the way for FieldExtensions.
Importing Extension from strawberry.extensions will now raise a deprecation
warning.
Before:
from strawberry.extensions import Extension
After:
from strawberry.extensions import SchemaExtension
Contributed by Jonathan Kim via PR #2574
This releases adds support for Mypy 1.1.1
Contributed by Patrick Arminio via PR #2616
This release changes how extension hooks are defined. The new style hooks are more flexible and allow to run code before and after the execution.
The old style hooks are still supported but will be removed in future releases.
Before:
def on_executing_start(self): # Called before the execution start
...
def on_executing_end(self): # Called after the execution ends
...
After
def on_execute(self):
# This part is called before the execution start
yield
# This part is called after the execution ends
Contributed by ניר via PR #2428
Add a type annotation to strawberry.fastapi.BaseContext's __init__ method so that
it can be used without mypy raising an error.
Contributed by Martin Winkel via PR #2581
Version 1.5.10 of GraphiQL disabled introspection for deprecated arguments because it wasn't supported by all GraphQL server versions. This PR enables it so that deprecated arguments show up again in GraphiQL.
Contributed by Jonathan Kim via PR #2575
Throw proper exceptions when Unions are created with invalid types
Previously, using Lazy types inside of Unions would raise unexpected, unhelpful errors.
Contributed by ignormies via PR #2540
This releases adds support for Apollo Federation 2.1, 2.2 and 2.3.
This includes support for @composeDirective and @interfaceObject,
we expose directives for both, but we also have shortcuts, for example
to use @composeDirective with a custom schema directive, you can do
the following:
@strawberry.federation.schema_directive(
locations=[Location.OBJECT], name="cacheControl", compose=True
)
class CacheControl:
max_age: int
The compose=True makes so that this directive is included in the supergraph
schema.
For @interfaceObject we introduced a new @strawberry.federation.interface_object
decorator. This works like @strawberry.federation.type, but it adds, the appropriate
directive, for example:
@strawberry.federation.interface_object(keys=["id"])
class SomeInterface:
id: strawberry.ID
generates the following type:
type SomeInterface @key(fields: "id") @interfaceObject {
id: ID!
}
Contributed by Patrick Arminio via PR #2549
This release fixes a regression introduce in version 0.156.2 that would make Mypy throw an error in the following code:
import strawberry
@strawberry.type
class Author:
name: str
@strawberry.type
class Query:
@strawberry.field
async def get_authors(self) -> list[Author]:
return [Author(name="Michael Crichton")]
Contributed by Patrick Arminio via PR #2535
This release adds support for Mypy 1.0
Contributed by Patrick Arminio via PR #2516
This release updates the typing for the resolver argument in
strawberry.fieldi to support async resolvers.
This means that now you won't get any type
error from Pyright when using async resolver, like the following example:
import strawberry
async def get_user_age() -> int:
return 0
@strawberry.type
class User:
name: str
age: int = strawberry.field(resolver=get_user_age)
Contributed by Patrick Arminio via PR #2528
Add GraphQLWebsocketCommunicator for testing websockets on channels.
i.e:
import pytest
from strawberry.channels.testing import GraphQLWebsocketCommunicator
from myapp.asgi import application
@pytest.fixture
async def gql_communicator():
async with GraphQLWebsocketCommunicator(
application=application, path="/graphql"
) as client:
yield client
async def test_subscribe_echo(gql_communicator):
async for res in gql_communicator.subscribe(
query='subscription { echo(message: "Hi") }'
):
assert res.data == {"echo": "Hi"}
Contributed by ניר via PR #2458
This release adds support for specialized generic types.
Before, the following code would give an error, saying that T was not
provided to the generic type:
@strawberry.type
class Foo(Generic[T]):
some_var: T
@strawberry.type
class IntFoo(Foo[int]): ...
@strawberry.type
class Query:
int_foo: IntFoo
Also, because the type is already specialized, Int won't get inserted to its name,
meaning it will be exported to the schema with a type name of IntFoo and not
IntIntFoo.
For example, this query:
@strawberry.type
class Query:
int_foo: IntFoo
str_foo: Foo[str]
Will generate a schema like this:
type IntFoo {
someVar: Int!
}
type StrFoo {
someVar: String!
}
type Query {
intFoo: IntFoo!
strfoo: StrFoo!
}
Contributed by Thiago Bellini Ribeiro via PR #2517
Fix file not found error when exporting schema with lazy types from CLI #2469
Contributed by San Kilkis via PR #2512
Fix missing custom resolve_reference for using pydantic with federation
i.e:
import typing
from pydantic import BaseModel
import strawberry
from strawberry.federation.schema_directives import Key
class ProductInDb(BaseModel):
upc: str
name: str
@strawberry.experimental.pydantic.type(
model=ProductInDb, directives=[Key(fields="upc", resolvable=True)]
)
class Product:
upc: str
name: str
@classmethod
def resolve_reference(cls, upc):
return Product(upc=upc, name="")
Contributed by filwaline via PR #2503
This release fixes a bug in subscriptions using the graphql-transport-ws protocol where the conversion of the NextMessage object to a dictionary took an unnecessary amount of time leading to an increase in CPU usage.
Contributed by rjwills28 via PR #2481
A link to the changelog has been added to the package metadata, so it shows up on PyPI.
Contributed by Tom Most via PR #2490
This release adds a new utility function to convert a Strawberry object to a dictionary.
You can use strawberry.asdict(...) function to convert a Strawberry object to
a dictionary:
@strawberry.type
class User:
name: str
age: int
# should be {"name": "Lorem", "age": 25}
user_dict = strawberry.asdict(User(name="Lorem", age=25))
Note: This function uses the
dataclasses.asdictfunction under the hood, so you can safely replacedataclasses.asdictwithstrawberry.asdictin your code. This will make it easier to update your code to newer versions of Strawberry if we decide to change the implementation.
Contributed by Haze Lee via PR #2417
Fix DuplicatedTypeName exception being raised on generics declared using
strawberry.lazy. Previously the following would raise:
# issue_2397.py
from typing import Annotated, Generic, TypeVar
import strawberry
T = TypeVar("T")
@strawberry.type
class Item:
name: str
@strawberry.type
class Edge(Generic[T]):
node: T
@strawberry.type
class Query:
edges_normal: Edge[Item]
edges_lazy: Edge[Annotated["Item", strawberry.lazy("issue_2397")]]
if __name__ == "__main__":
schema = strawberry.Schema(query=Query)
Contributed by pre-commit-ci via PR #2462
Support constrained float field types in Pydantic models.
i.e.
import pydantic
class Model(pydantic.BaseModel):
field: pydantic.confloat(le=100.0)
equivalent_field: float = pydantic.Field(le=100.0)
Contributed by Etienne Wodey via PR #2455
This change allows clients to define connectionParams when making Subscription requests similar to the way Apollo-Server does it.
With Apollo-Client (React) as an example, define a Websocket Link:
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
const wsLink = new GraphQLWsLink(createClient({
url: 'ws://localhost:4000/subscriptions',
connectionParams: {
authToken: user.authToken,
},
}));
and the JSON passed to connectionParams here will appear within Strawberry's context as the connection_params attribute when accessing info.context within a Subscription resolver.
Contributed by Tommy Smith via PR #2380
This release adds support for updating (or adding) the query document inside an
extension's on_request_start method.
This can be useful for implementing persisted queries. The old behavior of returning a 400 error if no query is present in the request is still supported.
Example usage:
from strawberry.extensions import Extension
def get_doc_id(request) -> str:
"""Implement this to get the document ID using your framework's request object"""
...
def load_persisted_query(doc_id: str) -> str:
"""Implement this load a query by document ID. For example, from a database."""
...
class PersistedQuery(Extension):
def on_request_start(self):
request = self.execution_context.context.request
doc_id = get_doc_id(request)
self.execution_context.query = load_persisted_query(doc_id)
Contributed by James Thorniley via PR #2431
This release adds support for FastAPI 0.89.0
Contributed by Patrick Arminio via PR #2440
This release fixes @strawberry.experimental.pydantic.type and adds support for the metadata attribute on fields.
Example:
@strawberry.experimental.pydantic.type(model=User)
class UserType:
private: strawberry.auto = strawberry.field(metadata={"admin_only": True})
public: strawberry.auto
Contributed by Huy Z via PR #2415
This release fixes an issue that prevented using generic that had a field of type enum. The following works now:
@strawberry.enum
class EstimatedValueEnum(Enum):
test = "test"
testtest = "testtest"
@strawberry.type
class EstimatedValue(Generic[T]):
value: T
type: EstimatedValueEnum
@strawberry.type
class Query:
@strawberry.field
def estimated_value(self) -> Optional[EstimatedValue[int]]:
return EstimatedValue(value=1, type=EstimatedValueEnum.test)
Contributed by Patrick Arminio via PR #2411
This PR adds a new graphql_type parameter to strawberry.field that allows you
to explicitly set the field type. This parameter will take preference over the
resolver return type and the class field type.
For example:
@strawberry.type
class Query:
a: float = strawberry.field(graphql_type=str)
b = strawberry.field(graphql_type=int)
@strawberry.field(graphql_type=float)
def c(self) -> str:
return "3.4"
schema = strawberry.Schema(Query)
str(schema) == """
type Query {
a: String!
b: Int!
c: Float!
}
"""
Contributed by Jonathan Kim via PR #2313
Fixed field resolvers with nested generic return types
(e.g. list, Optional, Union etc) raising TypeErrors.
This means resolver factory methods can now be correctly type hinted.
For example the below would previously error unless you ommited all the
type hints on resolver_factory and actual_resolver functions.
from typing import Callable, Optional, Type, TypeVar
import strawberry
@strawberry.type
class Cat:
name: str
T = TypeVar("T")
def resolver_factory(type_: Type[T]) -> Callable[[], Optional[T]]:
def actual_resolver() -> Optional[T]:
# load rows from database and cast to type etc
...
return actual_resolver
@strawberry.type
class Query:
cat: Cat = strawberry.field(resolver_factory(Cat))
schema = strawberry.Schema(query=Query)
Contributed by Tim OSullivan via PR #1900
This release implements the ability to use custom caching for dataloaders.
It also allows to provide a cache_key_fn to the dataloader. This function
is used to generate the cache key for the dataloader. This is useful when
you want to use a custom hashing function for the cache key.
Contributed by Aman Choudhary via PR #2394
This release fixes support for generics in arguments, see the following example:
T = TypeVar("T")
@strawberry.type
class Node(Generic[T]):
@strawberry.field
def data(self, arg: T) -> T: # `arg` is also generic
return arg
Contributed by A. Coady via PR #2316
This release improves the performance of rich exceptions on custom scalars
by changing how frames are fetched from the call stack.
Before the change, custom scalars were using a CPU intensive call to the
inspect module to fetch frame info which could lead to serious CPU spikes.
Contributed by Paulo Amaral via PR #2390
This release does some internal refactoring of the HTTP views, hopefully it doesn't affect anyone. It mostly changes the status codes returned in case of errors (e.g. bad JSON, missing queries and so on).
It also improves the testing, and adds an entirely new test suite for the HTTP views, this means in future we'll be able to keep all the HTTP views in sync feature-wise.
Contributed by Patrick Arminio via PR #1840
This release changes the get_context, get_root_value and process_result
methods of the Flask async view to be async functions. This allows you to use
async code in these methods.
Contributed by Patrick Arminio via PR #2388
This release introduces a encode_json method on all the HTTP integrations.
This method allows to customize the encoding of the JSON response. By default we
use json.dumps but you can override this method to use a different encoder.
It also deprecates json_encoder and json_dumps_params in the Django and
Sanic views, encode_json should be used instead.
Contributed by Patrick Arminio via PR #2272
This release updates the Sanic integration and includes some breaking changes.
You might need to update your code if you are customizing get_context or
process_result
get_contextget_context now receives the request as the first argument and the response as
the second argument.
process_resultprocess_result is now async and receives the request and the GraphQL execution
result.
This change is needed to align all the HTTP integrations and reduce the amount of code needed to maintain. It also makes the errors consistent with other integrations.
It also brings a new feature and it allows to customize the HTTP status code
by using info.context["response"].status_code = YOUR_CODE.
It also removes the upper bound on the Sanic version, so you can use the latest version of Sanic with Strawberry.
Contributed by Patrick Arminio via PR #2273
This release introduced improved errors! Now, when you have a syntax error in your code, you'll get a nice error message with a line number and a pointer to the exact location of the error. ✨
This is a huge improvement over the previous behavior, which was providing a stack trace with no clear indication of where the error was. 🙈
You can enable rich errors by installing Strawberry with the cli extra:
pip install "strawberry-graphql[cli]"
Contributed by Patrick Arminio via PR #2027
This release fixes an issue with type duplication of generics.
You can now use a lazy type with a generic even if the original type was already used with that generic in the schema.
Example:
@strawberry.type
class Query:
regular: Edge[User]
lazy: Edge[Annotated["User", strawberry.lazy(".user")]]
Contributed by Dmitry Semenov via PR #2381
Generic types are now allowed in the schema's extra types.
T = TypeVar("T")
@strawberry.type
class Node(Generic[T]):
field: T
@strawberry.type
class Query:
name: str
schema = strawberry.Schema(Query, types=[Node[int]])
Contributed by A. Coady via PR #2294
This release fixes a regression that prevented Generic types from being used multiple types.
Contributed by Patrick Arminio via PR #2378
Added extra validation that types used in a schema are unique.
Strawberry starts to throw an exception DuplicatedTypeName when two types defined in a schema have the same name.
Contributed by Bartosz Polnik via PR #2356
Added an error to be used when overriding GraphQLError in custom extensions and added a guide on how to use it. Exposing GraphQLError from the strawberry namespace brings a better experience and will be useful in the future (when we move to something else).
Contributed by Niten Nashiki via PR #2360
This release updates GraphiQL to 2.2.0 and fixes an issue with the websocket URL being incorrectly set when navigating to GraphiQL with an URL with a hash.
Contributed by Shen Li via PR #2363
This release changes the dataloader batch resolution to avoid resolving
futures that were canceled, and also from reusing them from the cache.
Trying to resolve a future that was canceled would raise asyncio.InvalidStateError
Contributed by Thiago Bellini Ribeiro via PR #2339
This release fixes a bug where using a custom scalar in a union would result
in an unclear exception. Instead, when using a custom scalar in a union,
the InvalidUnionType exception is raised with a clear message that you
cannot use that type in a union.
Contributed by Jonathan Kim via PR #2336
This release adds support for typing.Self and typing_extensions.Self for types and interfaces.
from typing_extensions import Self
@strawberry.type
class Node:
@strawberry.field
def field(self) -> Self:
return self
Contributed by A. Coady via PR #2295
This release adds support for an implicit resolve_reference method
on Federation type. This method will automatically create a Strawberry
instance for a federation type based on the input data received, for
example, the following:
@strawberry.federation.type(keys=["id"])
class Something:
id: str
@strawberry.federation.type(keys=["upc"])
class Product:
upc: str
something: Something
@staticmethod
def resolve_reference(**data):
return Product(upc=data["upc"], something=Something(id=data["something_id"]))
doesn't need the resolve_reference method anymore.
Contributed by Patrick Arminio via PR #2332
[Internal] Update StrawberryField so that type_annotation is always an instance of StrawberryAnnotation.
Contributed by Jonathan Kim via PR #2319
This release fixes an issue that prevented using enums that were using strawberry.enum_value, like the following example:
from enum import Enum
import strawberry
@strawberry.enum
class TestEnum(Enum):
A = strawberry.enum_value("A")
B = "B"
@strawberry.type
class Query:
@strawberry.field
def receive_enum(self, test: TestEnum) -> int:
return 0
schema = strawberry.Schema(query=Query)
Contributed by Patrick Arminio via PR #2306
This release adds logging back for parsing and validation errors that was accidentally removed in v0.135.0.
Contributed by Jonathan Kim via PR #2323
This release allows to disable operation logging when running the debug server.
strawberry server demo --log-operations False
Contributed by Patrick Arminio via PR #2310
This release changes the type resolution priority to prefer the field annotation over the resolver return type.
def my_resolver() -> str:
return "1.33"
@strawberry.type
class Query:
a: float = strawberry.field(resolver=my_resolver)
schema = strawberry.Schema(Query)
# Before:
str(schema) == """
type Query {
a: String!
}
"""
# After:
str(schema) == """
type Query {
a: Float!
}
"""
Contributed by Jonathan Kim via PR #2312
Fix Pydantic integration for Python 3.10.0 (which was missing the kw_only
parameter for dataclasses.make_dataclass()).
Contributed by Jonathan Kim via PR #2309
This release changes an internal implementation for FastAPI's GraphQL router. This should reduce overhead when using the context, and it shouldn't affect your code.
Contributed by Kristján Valur Jónsson via PR #2278
This release adds support for generic in arguments, see the following example:
T = TypeVar("T")
@strawberry.type
class Node(Generic[T]):
@strawberry.field
def data(self, arg: T) -> T: # `arg` is also generic
return arg
Contributed by A. Coady via PR #2293
Allowed CustomScalar | None syntax for python >= 3.10.
Contributed by Guillaume Andreu Sabater via PR #2279
This release fixes errors when using Union-of-lazy-types
Contributed by Paulo Costa via PR #2271
This release refactors the chalice integration in order to keep it consistent with the other integrations.
Passing render_graphiql is now deprecated, please use graphiql instead.
info.context["response"].status_code = 418allow_queries_via_get (defaults to True)Trying to access /graphql via a browser and with graphiql set to False will return a 404.
Contributed by Patrick Arminio via PR #2266
This release adds a new MaskErrors extension that can be used to hide error
messages from the client to prevent exposing sensitive details. By default it
masks all errors raised in any field resolver.
import strawberry
from strawberry.extensions import MaskErrors
schema = strawberry.Schema(
Query,
extensions=[
MaskErrors(),
],
)
Contributed by Jonathan Kim via PR #2248
This release improves the error message that you get when trying
to use an enum that hasn't been decorated with @strawberry.enum
inside a type's field.
Contributed by Rise Riyo via PR #2267
This release adds support for printing schema directives on an input type object, for example the following schema:
@strawberry.schema_directive(locations=[Location.INPUT_FIELD_DEFINITION])
class RangeInput:
min: int
max: int
@strawberry.input
class CreateUserInput:
name: str
age: int = strawberry.field(directives=[RangeInput(min=1, max=100)])
prints the following:
directive @rangeInput(min: Int!, max: Int!) on INPUT_FIELD_DEFINITION
input Input @sensitiveInput(reason: "GDPR") {
firstName: String!
age: Int! @rangeInput(min: 1, max: 100)
}
Contributed by Etty via PR #2233
This release fixes an issue that prevented using strawberry.lazy with relative paths.
The following should work now:
@strawberry.type
class TypeA:
b: Annotated["TypeB", strawberry.lazy(".type_b")]
Contributed by Paulo Costa via PR #2244
This release adds pyupgrade to our CI and includes some minor changes to keep our codebase modern.
Contributed by Liel Fridman via PR #2255
This release fixes an issue that prevented using lazy types inside generic types.
The following is now allowed:
T = TypeVar("T")
TypeAType = Annotated["TypeA", strawberry.lazy("tests.schema.test_lazy.type_a")]
@strawberry.type
class Edge(Generic[T]):
node: T
@strawberry.type
class Query:
users: Edge[TypeAType]
Contributed by Patrick Arminio via PR #2254
These release allow you to define a different url in the GraphQLTestClient, the default is "/graphql/".
Here's an example with Starlette client:
import pytest
from starlette.testclient import TestClient
from strawberry.asgi.test import GraphQLTestClient
@pytest.fixture
def graphql_client() -> GraphQLTestClient:
return GraphQLTestClient(
TestClient(app, base_url="http://localhost:8000"), url="/api/"
)
Contributed by Etty via PR #2238
This release fixes a type issue when passing scalar_overrides to strawberry.Schema
Contributed by Patrick Arminio via PR #2251
Fix support for arguments where arg.type=LazyType["EnumType"]
Contributed by Paulo Costa via PR #2245
Updated unset import, from strawberry.arguments to strawberry.unset in codebase.
This will prevent strawberry from triggering its own warning on deprecated imports.
Contributed by dependabot via PR #2219
This release fixes the type of strawberry.federation.field, this will prevent errors from mypy and pyright when doing the following:
@strawberry.federation.type(keys=["id"])
class Location:
id: strawberry.ID
# the following field was reporting an error in mypy and pylance
celestial_body: CelestialBody = strawberry.federation.field(
resolver=resolve_celestial_body
)
Contributed by Patrick Arminio via PR #2222
This release allows to create a federation schema without having to pass a
Query type. This is useful when your schema only extends some types without
adding any additional root field.
@strawberry.federation.type(keys=["id"])
class Location:
id: strawberry.ID
name: str = strawberry.federation.field(override="start")
schema = strawberry.federation.Schema(types=[Location])
Contributed by Patrick Arminio via PR #2220
This release fixes an issue with strawberry.federation.field that
prevented instantiating field when passing a resolver function.
Contributed by Patrick Arminio via PR #2218
This release fixes an issue that prevented using strawberry.field with
UNSET as the default value.
Contributed by Patrick Arminio via PR #2128
Reduce the number of required dependencies, by marking Pygments and python-multipart as optional. These dependencies are still necessary for some functionality, and so users of that functionality need to ensure they're installed, either explicitly or via an extra:
strawberry-graphql[debug-server] extra.strawberry.file_uploads.Upload with FastAPI or Starlette, and is included in the strawberry-graphql[fastapi] and strawberry-graphql[asgi] extras, respectively.There is now also the strawberry-graphql[cli] extra to support commands like strawberry codegen and strawberry export-schema.
Contributed by Huon Wilson via PR #2205
Improve resolving performance by avoiding extra calls for basic fields.
This change improves performance of resolving a query by skipping Info
creation and permission checking for fields that don't have a resolver
or permission classes. In local benchmarks it improves performance of large
results by ~14%.
Contributed by Jonathan Kim via PR #2194
Support storing metadata in strawberry fields.
Contributed by Paulo Costa via PR #2190
Fixes false positives with the mypy plugin.
Happened when to_pydantic was called on a type that was converted
pydantic with all_fields=True.
Also fixes the type signature when to_pydantic is defined by the user.
from pydantic import BaseModel
from typing import Optional
import strawberry
class MyModel(BaseModel):
email: str
password: Optional[str]
@strawberry.experimental.pydantic.input(model=MyModel, all_fields=True)
class MyModelStrawberry: ...
MyModelStrawberry(email="").to_pydantic()
# previously would complain wrongly about missing email and password
Contributed by James Chua via PR #2017
This release updates the mypy plugin and the typing for Pyright to treat all strawberry fields as keyword-only arguments. This reflects a previous change to the Strawberry API.
Contributed by Paulo Costa via PR #2191
Bug fix: Do not force kw-only=False in fields specified with strawberry.field()
Contributed by Paulo Costa via PR #2189
This release fixes a small issue that might happen when uploading files and not passing the operations object.
Contributed by Patrick Arminio via PR #2192
Fix warnings during unit tests for Sanic's upload.
Otherwise running unit tests results in a bunch of warning like this:
DeprecationWarning: Use 'content=<...>' to upload raw bytes/text content.
Contributed by Paulo Costa via PR #2178
This release improves the dataloader class with new features:
Contributed by Paulo Costa via PR #2149
This release adds improved support for Pyright and Pylance, VSCode default language server for Python.
Using strawberry.type, strawberry.field, strawberry.input and
strawberry.enum will now be correctly recognized by Pyright and Pylance and
won't show errors.
Contributed by Patrick Arminio via PR #2172
Fix invalid deprecation warning issued on arguments annotated
by a subclassed strawberry.types.Info.
Thanks to @ThirVondukr for the bug report!
Example:
class MyInfo(Info):
pass
@strawberry.type
class Query:
@strawberry.field
def is_tasty(self, info: MyInfo) -> bool:
"""Subclassed ``info`` argument no longer raises deprecation warning."""
Contributed by San Kilkis via PR #2137
This release fixes the conversion of generic aliases when using pydantic.
Contributed by Silas Sewell via PR #2152
Fix version parsing issue related to dev builds of Mypy in strawberry.ext.mypy_plugin
Contributed by San Kilkis via PR #2157
Convert Tuple and Sequence types to GraphQL list types.
Example:
from collections.abc import Sequence
from typing import Tuple
@strawberry.type
class User:
pets: Sequence[Pet]
favourite_ice_cream_flavours: Tuple[IceCreamFlavour]
Contributed by Jonathan Kim via PR #2164
This release adds strawberry.lazy which allows you to define the type of the
field and its path. This is useful when you want to define a field with a type
that has a circular dependency.
For example, let's say we have a User type that has a list of Post and a
Post type that has a User:
# posts.py
from typing import TYPE_CHECKING, Annotated
import strawberry
if TYPE_CHECKING:
from .users import User
@strawberry.type
class Post:
title: str
author: Annotated["User", strawberry.lazy(".users")]
# users.py
from typing import TYPE_CHECKING, Annotated, List
import strawberry
if TYPE_CHECKING:
from .posts import Post
@strawberry.type
class User:
name: str
posts: List[Annotated["Post", strawberry.lazy(".posts")]]
Contributed by Patrick Arminio via PR #2158
This release changes how dataclasses are created to make use of the new
kw_only argument in Python 3.10 so that fields without a default value can now
follow a field with a default value. This feature is also backported to all other
supported Python versions.
More info: https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass
For example:
# This no longer raises a TypeError
@strawberry.type
class MyType:
a: str = "Hi"
b: int
⚠️ This is a breaking change! Whenever instantiating a Strawberry type make sure that you only pass values are keywo
This release adds support for custom classes inside the OpenTelemetry integration. With this, we shouldn’t see errors like this anymore:
Invalid type dict for attribute 'graphql.param.paginator' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types.
Contributed by Budida Abhinav Ramana via PR #2753
Add get_argument_definition helper function on the Info object to get a StrawberryArgument definition by argument name from inside a resolver or Field
Add get_argument_definition helper function on the Info object to get a StrawberryArgument definition by argument name from inside a resolver or Field Extension.
Example:
import strawberry
@strawberry.type
class Query :
@strawberry.field
def field (
self ,
info ,
my_input : Annotated[
str ,
strawberry.argument( description = "Some description" ),
],
) -> str :
my_input_def = info.get_argument_definition( "my_input" )
assert my_input_def.type is str
assert my_input_def.description == "Some description"
return my_input
Contributed by Jonathan Kim via PR #2732
This release adds more type hints to internal APIs and public APIs.
This release adds more type hints to internal APIs and public APIs.
Contributed by Alex Auritt via PR #2568
This release improves the graphql-transport-ws implementation by starting the sub-protocol timeout only when the connection handshake is completed.
This release improves the graphql-transport-ws implementation by starting the sub-protocol timeout only when the connection handshake is completed.
Contributed by Kristján Valur Jónsson via PR #2703
This release parses the input arguments to a field earlier so that Field Extensions recieve instances of Input types rather than plain dictionaries.
This release parses the input arguments to a field earlier so that Field Extensions recieve instances of Input types rather than plain dictionaries.
Example:
import strawberry
from strawberry.extensions import FieldExtension
@strawberry.input
class MyInput :
foo: str
class MyFieldExtension ( FieldExtension ):
def resolve (
self , next_ : Callable[..., Any], source : Any, info : strawberry.Info, ** kwargs
):
...
@strawberry.type
class Query :
@strawberry.field
def field ( self , my_input : MyInput) -> str :
return "hi"
Contributed by Jonathan Kim via PR #2731
This release adds a missing parameter to get_context when using subscriptions with ASGI.
This release adds a missing parameter to get_context when using subscriptions with ASGI.
Contributed by Patrick Arminio via PR #2739
Do not display graphiql view in fastapi doc if graphiql parameter is deactivated
Do not display graphiql view in fastapi doc if graphiql parameter is deactivated
Contributed by yak-toto via PR #2736
This PR adds a MaxTokensLimiter extension which limits the number of tokens in a GraphQL document.
This PR adds a MaxTokensLimiter extension which limits the number of tokens in a GraphQL document.
This release bumps the version of typing_extensions to >= 4.0.0 to fix the error: "cannot import Self from typing_extensions" .
This release bumps the version of typing_extensions to >= 4.0.0 to fix the error: "cannot import Self from typing_extensions" .
Contributed by Tien Truong via PR #2704
This releases adds an extension for PyInstrument . It allows to instrument your server and find slow code paths.
This releases adds an extension for PyInstrument . It allows to instrument your server and find slow code paths.
You can use it like this:
import strawberry
from strawberry.extensions import pyinstrument
schema = strawberry.Schema(
Query,
extensions =[
pyinstrument.PyInstrument( report_path = "pyinstrument.html" ),
],
)
Contributed by Peyton Duncan via PR #2727
This PR adds a MaxAliasesLimiter extension which limits the number of aliases in a GraphQL document.
This PR adds a MaxAliasesLimiter extension which limits the number of aliases in a GraphQL document.
This release adds missing annotations in class methods, improving our type coverage.
This release adds missing annotations in class methods, improving our type coverage.
Contributed by Kai Benevento via PR #2721
graphql_transport_ws : Cancelling a subscription no longer blocks the connection while any subscription finalizers run.
graphql_transport_ws : Cancelling a subscription no longer blocks the connection while any subscription finalizers run.
Contributed by Kristján Valur Jónsson via PR #2718
This release fix the return value of enums when using a custom name converter for them.
This release fix the return value of enums when using a custom name converter for them.
Contributed by Patrick Arminio via PR #2696
This release adds support for Mypy 1.2.0
This release adds support for Mypy 1.2.0
Contributed by Patrick Arminio via PR #2693
This release add support for converting the enum value names from NameConverter . It looks like this:
This release add support for converting the enum value names from NameConverter . It looks like this:
from enum import Enum
import strawberry
from strawberry.enum import EnumDefinition, EnumValue
from strawberry.schema.config import StrawberryConfig
from strawberry.schema.name_converter import NameConverter
class EnumNameConverter ( NameConverter ):
def from_enum_value ( self , enum : EnumDefinition, enum_value : EnumValue) -> str :
return f " { super ().from_enum_value(enum, enum_value) } _enum_value"
@strawberry.enum
class MyEnum ( Enum ):
A = "a"
B = "b"
@strawberry.type
class Query :
a_enum: MyEnum
schema = strawberry.Schema(
query =Query,
config =StrawberryConfig( name_converter =EnumNameConverter()),
)
Contributed by Patrick Arminio via PR #2690
Unfortunately, this release does contain some breaking changes, but they are minimal and should be quick to fix.
This release updates all* the HTTP integration to use the same base class, which makes it easier to maintain and extend them in future releases.
While this doesn’t provide any new features (other than settings headers in Chalice and Sanic), it does make it easier to extend the HTTP integrations in the future. So, expect some new features in the next releases!
New features:
Now both Chalice and Sanic integrations support setting headers in the response. Bringing them to the same level as the other HTTP integrations.
Breaking changes:
Unfortunately, this release does contain some breaking changes, but they are minimal and should be quick to fix.
Flask get_root_value and get_context now receive the request
Sanic get_root_value now receives the request and it is async
Contributed by Patrick Arminio via PR #2681
Fixes type hint for StrawberryTypeFromPydantic._pydantic_type to be a Type instead of an instance of the Pydantic model. As it is a private API, we st
Fixes type hint for StrawberryTypeFromPydantic._pydantic_type to be a Type instead of an instance of the Pydantic model. As it is a private API, we still highly discourage using it, but it’s now typed correctly.
from pydantic import BaseModel
from typing import Type, List
import strawberry
from strawberry.experimental.pydantic.conversion_types import StrawberryTypeFromPydantic
class User ( BaseModel ):
name: str
@ staticmethod
def foo () -> List[ str ]:
return [ "Patrick" , "Pietro" , "Pablo" ]
@strawberry.experimental.pydantic.type ( model =User, all_fields = True )
class UserType :
@strawberry.field
def foo ( self : StrawberryTypeFromPydantic[User]) -> List[ str ]:
pydantic_type: Type[User] = self ._pydantic_type
return pydantic_type.foo()
def get_users () -> UserType:
user: User = User( name = "Patrick" )
return UserType.from_pydantic(user)
@strawberry.type
class Query :
user: UserType = strawberry.field( resolver =get_users)
schema = strawberry.Schema( query =Query)
Contributed by James Chua via PR #2683
This releases adds a new extra group for Starlite, preventing it from being installed by default.
This releases adds a new extra group for Starlite, preventing it from being installed by default.
Contributed by Patrick Arminio via PR #2664
This release adds support for starlite .
This release adds support for starlite .
import strawberry
from starlite import Request, Starlite
from strawberry.starlite import make_graphql_controller
from strawberry.types.info import Info
def custom_context_getter ( request : Request):
return { "custom" : "context" }
@strawberry.type
class Query :
@strawberry.field
def hello ( self , info : strawberry.Info[ object , None ]) -> str :
return info.context[ "custom" ]
schema = strawberry.Schema(Query)
GraphQLController = make_graphql_controller(
schema,
path = "/graphql" ,
context_getter =custom_context_getter,
)
app = Starlite(
route_handlers =[GraphQLController],
)
Contributed by Matthieu MN via PR #2391
This release fixes and issue where you’d get a warning about using Apollo Federation directives even when using strawberry.federation.Schema .
This release fixes and issue where you’d get a warning about using Apollo Federation directives even when using strawberry.federation.Schema .
Contributed by Patrick Arminio via PR #2661
This releases adds more type annotations for public functions and methods.
This releases adds more type annotations for public functions and methods.
No new changes have been added to the API.
Contributed by Jad Haddad via PR #2627
This release adds a warning when using @strawberry.federation.type but not using strawberry.federation.Schema
This release adds a warning when using @strawberry.federation.type but not using strawberry.federation.Schema
Contributed by Rubens O Leão via PR #2572
Updates the MaskErrors extension to the new extension API, which was missed previously.
Updates the MaskErrors extension to the new extension API, which was missed previously.
Contributed by Nikolai Maas via PR #2655
Your coding agent can read these notes before it upgrades. Set up the MCP server →