NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1573 most downloaded on PyPI
A library for creating GraphQL APIs
Last release today
04 Oct 2026
Ships fairly regularly
a new release about every 3 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
1125 releases · first in 2019
This release adds a backward compatibility layer with libraries that specify a custom get_result .
This release adds a backward compatibility layer with libraries that specify a custom get_result .
Contributed by Patrick Arminio via PR #2038
Nothing published for this version
This release adds support for overriding the default resolver for fields.
This release adds support for overriding the default resolver for fields.
Currently the default resolver is getattr , but now you can change it to any function you like, for example you can allow returning dictionaries:
@strawberry.type
class User :
name: str
@strawberry.type
class Query :
@strawberry.field
def user ( self ) -> User:
return { "name" : "Patrick" } # type: ignore
schema = strawberry.Schema(
query =Query,
config =StrawberryConfig( default_resolver =getitem),
)
query = "{ user { name } }"
result = schema.execute_sync(query)
Contributed by Patrick Arminio via PR #2037
One column per quarter.
This release add a new DatadogTracingExtension that can be used to instrument your application with Datadog.
This release add a new DatadogTracingExtension that can be used to instrument your application with Datadog.
import strawberry
from strawberry.extensions.tracing import DatadogTracingExtension
schema = strawberry.Schema(
Query,
extensions =[
DatadogTracingExtension,
],
)
Contributed by Patrick Arminio via PR #2001
Nothing published for this version
Nothing published for this version
Fixed edge case where Union types raised an UnallowedReturnTypeForUnion error when returning the correct type from the resolver. This also improves pe
Fixed edge case where Union types raised an UnallowedReturnTypeForUnion error when returning the correct type from the resolver. This also improves performance of StrawberryUnion’s _resolve_union_type from O(n) to O(1) in the majority of cases where n is the number of types in the schema.
For example the below ) would previously raise the error when querying two as StrawberryUnion would incorrectly determine that the resolver returns Container[TypeOne] .
import strawberry
from typing import TypeVar, Generic, Union, List, Type
T = TypeVar( "T" )
@strawberry.type
class Container (Generic[T]):
items: List[T]
@strawberry.type
class TypeOne :
attr: str
@strawberry.type
class TypeTwo :
attr: str
def resolver_one ():
return Container( items =[TypeOne( "one" )])
def resolver_two ():
return Container( items =[TypeTwo( "two" )])
@strawberry.type
class Query :
one: Union[Container[TypeOne], TypeOne] = strawberry.field(resolver_one)
two: Union[Container[TypeTwo], TypeTwo] = strawberry.field(resolver_two)
schema = strawberry.Schema( query =Query)
Contributed by Tim OSullivan via PR #2029
An explanatory custom exception is raised when union of GraphQL input types is attempted.
An explanatory custom exception is raised when union of GraphQL input types is attempted.
Contributed by Dhanshree Arora via PR #2019
This release changes when we add the custom directives extension, previously the extension was always enabled, now it is only enabled if you pass cust
This release changes when we add the custom directives extension, previously the extension was always enabled, now it is only enabled if you pass custom directives to strawberry.Schema .
Contributed by bomtall via PR #2020
Nothing published for this version
This release adds an initial fix to make strawberry.auto work when using from __future__ import annotations .
This release adds an initial fix to make strawberry.auto work when using from future import annotations .
Contributed by Patrick Arminio via PR #1994
Nothing published for this version
Fixes issue where users without pydantic were not able to use the mypy plugin.
Fixes issue where users without pydantic were not able to use the mypy plugin.
Contributed by James Chua via PR #2016
Nothing published for this version
You can now pass keyword arguments to to_pydantic
You can now pass keyword arguments to to_pydantic
from pydantic import BaseModel
import strawberry
class MyModel ( BaseModel ):
email: str
password: str
@strawberry.experimental.pydantic.input ( model =MyModel)
class MyModelStrawberry :
email: strawberry.auto
MyModelStrawberry( email = "" ).to_pydantic( password = "hunter" )
Also if you forget to pass password, mypy will complain
MyModelStrawberry( email = "" ).to_pydantic()
Contributed by James Chua via PR #2012
Nothing published for this version
Allow to add alias to fields generated from pydantic with strawberry.field(name="ageAlias") .
Allow to add alias to fields generated from pydantic with strawberry.field(name="ageAlias") .
class User(pydantic.BaseModel):
age: int
@strawberry.experimental.pydantic.type(User)
class UserType:
age: strawberry.auto = strawberry.field(name="ageAlias")
Contributed by Alex via PR #1986
This release fixes an issue that required installing opentelemetry when trying to use the ApolloTracing extension
This release fixes an issue that required installing opentelemetry when trying to use the ApolloTracing extension
Contributed by Patrick Arminio via PR #1977
Nothing published for this version
Fix regression caused by the new resolver argument handling mechanism introduced in v0.115.0. This release restores the ability to use unhashable defa
Fix regression caused by the new resolver argument handling mechanism introduced in v0.115.0. This release restores the ability to use unhashable default values in resolvers such as dict and list. See example below:
@strawberry.type
class Query :
@strawberry.field
def field ( self , x : List[ str ] = [ "foo" ], y : JSON = { "foo" : 42 }) -> str : # noqa: B006
return f " { x } { y } "
Thanks to @coady for the regression report!
Contributed by San Kilkis via PR #1985
This release fixes the following error when trying to use Strawberry with Apollo Federation:
This release fixes the following error when trying to use Strawberry with Apollo Federation:
Error: A valid schema couldn't be composed. The following composition errors were found:
[burro-api] Unknown type _FieldSet
Contributed by Patrick Arminio via PR #1988
Reimplement StrawberryResolver.annotations property after removal in v0.115.
Reimplement StrawberryResolver.annotations property after removal in v0.115.
Library authors who previously relied on the public annotations property can continue to do so after this fix.
Contributed by San Kilkis via PR #1990
Nothing published for this version
Nothing published for this version
This release fixes a breaking internal error in mypy plugin for the following case.
This release fixes a breaking internal error in mypy plugin for the following case.
failed: str = strawberry.field(resolver)
successed: str = strawberry.field( resolver =resolver)
now mypy returns an error with "field()" or "mutation()" only takes keyword arguments message rather than an internal error.
Contributed by cake-monotone via PR #1987
This release adds a link from generated GraphQLCore types to the Strawberry type that generated them.
This release adds a link from generated GraphQLCore types to the Strawberry type that generated them.
From a GraphQLCore type you can now access the Strawberry type by doing:
strawberry_type: TypeDefinition = graphql_core_type.extensions[
GraphQLCoreConverter.DEFINITION_BACKREF
]
Contributed by Paulo Costa via PR #1766
Note: the old way of passing arguments by name is deprecated and will be removed in future releases of Strawberry.
This release changes how we declare the info argument in resolvers and the value argument in directives.
Previously we’d use the name of the argument to determine its value. Now we use the type annotation of the argument to determine its value.
Here’s an example of how the old syntax works:
def some_resolver ( info ) -> str :
return info.context.get( "some_key" , "default" )
@strawberry.type
class Example :
a_field: str = strawberry.resolver(some_resolver)
and here’s an example of how the new syntax works:
from strawberry.types import Info
def some_resolver ( info : strawberry.Info) -> str :
return info.context.get( "some_key" , "default" )
@strawberry.type
class Example :
a_field: str = strawberry.resolver(some_resolver)
This means that you can now use a different name for the info argument in your resolver and the value argument in your directive.
Here’s an example that uses a custom name for both the value and the info parameter in directives:
from strawberry.types import Info
from strawberry.directive import DirectiveLocation, DirectiveValue
@strawberry.type
class Cake :
frosting: Optional[ str ] = None
flavor: str = "Chocolate"
@strawberry.type
class Query :
@strawberry.field
def cake ( self ) -> Cake:
return Cake()
@strawberry.directive (
locations =[DirectiveLocation.FIELD],
description = "Add frosting with value to a cake." ,
)
def add_frosting ( value : str , v : DirectiveValue[Cake], my_info : strawberry.Info):
DirectiveValue is supported!assert isinstance (v, Cake)
if (
value in my_info.context[ "allergies" ]
): # Info can now be accessed from directives!
raise AllergyError( "You are allergic to this frosting!" )
else :
v.frosting = value # Value can now be used as a GraphQL argument name!
return v
Note: the old way of passing arguments by name is deprecated and will be removed in future releases of Strawberry.
Contributed by San Kilkis via PR #1713
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Allow use of implicit Any in strawberry.Private annotated Generic types.
Allow use of implicit Any in strawberry.Private annotated Generic types.
For example the following is now supported:
from future import annotations
from typing import Generic, Sequence, TypeVar
import strawberry
T = TypeVar( "T" )
@strawberry.type
class Foo (Generic[T]):
private_field: strawberry.Private[Sequence] # instead of Sequence[Any]
@strawberry.type
class Query :
@strawberry.field
def foo ( self ) -> Foo[ str ]:
return Foo( private_field =[ 1 , 2 , 3 ])
See Issue #1938 for details.
Contributed by San Kilkis via PR #1939
The federation decorator now allows for a list of additional arbitrary schema directives extending the key/shareable directives used for federation.
The federation decorator now allows for a list of additional arbitrary schema directives extending the key/shareable directives used for federation.
Example Python:
import strawberry
from strawberry.schema.config import StrawberryConfig
from strawberry.schema_directive import Location
@strawberry.schema_directive ( locations =[Location.OBJECT])
class CacheControl :
max_age: int
@strawberry.federation.type (
keys =[ "id" ], shareable = True , extend = True , directives =[CacheControl( max_age = 42 )]
)
class FederatedType :
id : strawberry.ID
schema = strawberry.Schema( query =Query, config =StrawberryConfig( auto_camel_case = False ))
Resulting GQL Schema:
directive @CacheControl ( max_age : Int !) on OBJECT
directive @key ( fields : _FieldSet !, resolvable : Boolean ) on OBJECT | INTERFACE
directive @shareable on FIELD_DEFINITION | OBJECT
extend type FederatedType
@key ( fields : "id" )
@shareable
@CacheControl ( max_age : 42 ) {
id : ID !
}
type Query {
federatedType : FederatedType !
}
Contributed by Jeffrey DeFond via PR #1945
This release adds support in Mypy for using strawberry.mutation while passing a resolver, the following now doesn’t make Mypy return an error:
This release adds support in Mypy for using strawberry.mutation while passing a resolver, the following now doesn’t make Mypy return an error:
import strawberry
def set_name ( self , name : str ) -> None :
self .name = name
@strawberry.type
class Mutation :
set_name: None = strawberry.mutation( resolver =set_name)
Contributed by Etty via PR #1966
This release fixes the type annotation of Response.errors used in the GraphQLTestClient to be a List of GraphQLFormattedError .
This release fixes the type annotation of Response.errors used in the GraphQLTestClient to be a List of GraphQLFormattedError .
Contributed by Etty via PR #1961
This release fixes the type annotation of Response.errors used in the GraphQLTestClient to be a List of GraphQLError .
This release fixes the type annotation of Response.errors used in the GraphQLTestClient to be a List of GraphQLError .
Contributed by Etty via PR #1959
This release fixes an issue in the GraphQLTestClient when using both variables and files together.
This release fixes an issue in the GraphQLTestClient when using both variables and files together.
Contributed by Etty via PR #1576
Fix crash in Django’s HttpResponse.__repr__ by handling status_code=None in TemporalHttpResponse.__repr__ .
Fix crash in Django’s HttpResponse.repr by handling status_code=None in TemporalHttpResponse.repr .
Contributed by Daniel Hahler via PR #1950
Improve schema directives typing and printing after latest refactor.
Improve schema directives typing and printing after latest refactor.
Support for printing schema directives for non-scalars (e.g. types) and null values.
Also print the schema directive itself and any extra types defined in it
Fix typing for apis expecting directives (e.g. strawberry.field , strawberry.type , etc) to expect an object instead of a StrawberrySchemaDirective , which is now an internal type.
Contributed by Thiago Bellini Ribeiro via PR #1723
Nothing published for this version
This release adds support for Starlette 0.18 to 0.20
This release adds support for Starlette 0.18 to 0.20
It also removes upper bound dependencies limit for starlette, allowing you to install the latest version without having to wait for a new release of Strawberry
Contributed by Timothy Pansino via PR #1594
This release adds a new flask view to allow for aysnc dispatching of requests.
This release adds a new flask view to allow for aysnc dispatching of requests.
This is especially useful when using dataloaders with flask.
from strawberry.flask.views import AsyncGraphQLView
...
app.add_url_rule(
"/graphql" ,
view_func =AsyncGraphQLView.as_view( "graphql_view" , schema =schema, **kwargs),
)
Contributed by Scott Weitzner via PR #1907
This release fixes resolvers using functions with generic type variables raising a MissingTypesForGenericError error.
This release fixes resolvers using functions with generic type variables raising a MissingTypesForGenericError error.
For example a resolver factory like the below can now be used:
import strawberry
from typing import Type, TypeVar
T = TypeVar( "T" ) # or TypeVar("T", bound=StrawberryType) etc
def resolver_factory ( strawberry_type : Type[T]):
def resolver ( id : strawberry.ID) -> T:
return strawberry_type(...)
return resolver
Contributed by Tim OSullivan via PR #1891
Rename internal variable custom_getter in FastAPI router implementation.
Rename internal variable custom_getter in FastAPI router implementation.
Contributed by Gary Donovan via PR #1875
This release adds support for Apollo Federation 2 directives:
This release adds support for Apollo Federation 2 directives:
@shareable
@tag
@override
@inaccessible
This release does not add support for the @link directive.
This release updates the @key directive to align with Apollo Federation 2 updates.
See the below code snippet and/or the newly-added test cases for examples on how to use the new directives. The below snippet demonstrates the @override directive.
import strawberry
from typing import List
@strawberry.interface
class SomeInterface :
id : strawberry.ID
@strawberry.federation.type ( keys =[ "upc" ], extend = True )
class Product ( SomeInterface ):
upc: str = strawberry.federation.field( external = True , override =[ "mySubGraph" ])
@strawberry.federation.type
class Query :
@strawberry.field
def top_products ( self , first : int ) -> List[Product]:
return []
schema = strawberry.federation.Schema( query =Query)
should return:
extend type Product implements SomeInterface @key ( fields : "upc" , resolvable : "True" ) {
id : ID !
upc : String ! @external @override ( from : "mySubGraph" )
}
type Query {
_service : _Service !
_entities ( representations : [ _Any !]!): [ _Entity ]!
topProducts ( first : Int !): [ Product !]!
}
interface SomeInterface {
id : ID !
}
scalar _Any
union _Entity = Product
type _Service {
sdl : String !
}
Contributed by Matt Skillman via PR #1874
Nothing published for this version
Nothing published for this version
This release adds support for passing a custom name to schema directives fields, by using strawberry.directive_field .
This release adds support for passing a custom name to schema directives fields, by using strawberry.directive_field .
import strawberry
@strawberry.schema_directive ( locations =[Location.FIELD_DEFINITION])
class Sensitive :
reason: str = strawberry.directive_field( name = "as" )
real_age_2: str = strawberry.directive_field( name = "real_age" )
@strawberry.type
class Query :
first_name: str = strawberry.field(
directives =[Sensitive( reason = "GDPR" , real_age_2 = "42" )]
)
should return:
type Query {
firstName : String ! @sensitive ( as : "GDPR" , real_age : "42" )
}
Contributed by Patrick Arminio via PR #1871
This release adds support for Mypy 0.950
This release adds support for Mypy 0.950
Contributed by dependabot via PR #1855
Changed the location of UNSET from arguments.py to unset.py . UNSET can now also be imported directly from strawberry . Deprecated the is_unset method…
Changed the location of UNSET from arguments.py to unset.py . UNSET can now also be imported directly from strawberry . Deprecated the is_unset method in favor of the builtin is operator:
from strawberry import UNSET
from strawberry.arguments import is_unset # old
a = UNSET
assert a is UNSET # new
assert is_unset(a) # old
Further more a new subsection to the docs was added explaining this.
Contributed by Dominique Garmier via PR #1813
Fixes a bug when converting pydantic models with NewTypes in a List. This no longers causes an exception.
Fixes a bug when converting pydantic models with NewTypes in a List. This no longers causes an exception.
from typing import List, NewType
from pydantic import BaseModel
import strawberry
password = NewType( "password" , str )
class User ( BaseModel ):
passwords: List[password]
@strawberry.experimental.pydantic.type (User)
class UserType :
passwords: strawberry.auto
Contributed by James Chua via PR #1770
Fixes mypy type inference when using @strawberry.experimental.pydantic.input and @strawberry.experimental.pydantic.interface decorators
Fixes mypy type inference when using @strawberry.experimental.pydantic.input and @strawberry.experimental.pydantic.interface decorators
Contributed by James Chua via PR #1832
Refactoring: Move enum deserialization logic from convert_arguments to CustomGraphQLEnumType
Refactoring: Move enum deserialization logic from convert_arguments to CustomGraphQLEnumType
Contributed by Paulo Costa via PR #1765
Added support for deprecating Enum values with deprecation_reason while using strawberry.enum_value instead of string definition.
Added support for deprecating Enum values with deprecation_reason while using strawberry.enum_value instead of string definition.
@strawberry.enum
class IceCreamFlavour ( Enum ):
VANILLA = strawberry.enum_value( "vanilla" )
STRAWBERRY = strawberry.enum_value( "strawberry" , deprecation_reason = "We ran out" )
CHOCOLATE = "chocolate"
Contributed by Mateusz Sobas via PR #1720
This release fixes an issue in the previous release where requests using query params did not support passing variable values. Variables passed by que
This release fixes an issue in the previous release where requests using query params did not support passing variable values. Variables passed by query params are now parsed from a string to a dictionary.
Contributed by Matt Exact via PR #1820
This release adds support in all our integration for queries via GET requests. This behavior is enabled by default, but you can disable it by passing
This release adds support in all our integration for queries via GET requests. This behavior is enabled by default, but you can disable it by passing allow_queries_via_get=False to the constructor of the integration of your choice.
For security reason only queries are allowed via GET requests.
Contributed by Matt Exact via PR #1686
Correctly parse Decimal scalar types to avoid floating point errors
Correctly parse Decimal scalar types to avoid floating point errors
Contributed by Marco Acierno via PR #1811
Allow all data types in Schema(types=[...])
Allow all data types in Schema(types=[...])
Contributed by Paulo Costa via PR #1714
This release fixes a number of problems with single-result-operations over graphql-transport-ws protocol
This release fixes a number of problems with single-result-operations over graphql-transport-ws protocol
operation IDs now share the same namespace as streaming operations meaning that they cannot be reused while the others are in operation
single-result-operations now run as tasks meaning that messages related to them can be overlapped with other messages on the websocket.
single-result-operations can be cancelled with the complete message.
IDs for single result and streaming result operations are now released once the operation is done, allowing them to be re-used later, as well as freeing up resources related to previous requests.
Contributed by Kristján Valur Jónsson via PR #1792
This release adds an implementation of the GraphQLTestClient for the aiohttp integration (in addition to the existing asgi and Django support). It hid
This release adds an implementation of the GraphQLTestClient for the aiohttp integration (in addition to the existing asgi and Django support). It hides the HTTP request’s details and verifies that there are no errors in the response (this behavior can be disabled by passing asserts_errors=False ). This makes it easier to test queries and makes your tests cleaner.
If you are using pytest you can add a fixture in conftest.py
import pytest
from strawberry.aiohttp.test.client import GraphQLTestClient
@pytest.fixture
def graphql_client ( aiohttp_client , myapp ):
yield GraphQLTestClient(aiohttp_client(myapp))
And use it everywhere in your tests
def test_strawberry ( graphql_client ):
query = """
query Hi($name: String!) {
hi(name: $name)
}
"""
result = graphql_client.query(query, variables ={ "name" : "🍓" })
assert result.data == { "hi" : "Hi 🍓!" }
Contributed by Etty via PR #1604
Your coding agent can read these notes before it upgrades. Set up the MCP server →