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 16 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
This change fixes GET request queries returning a 400 if a content_type header is supplied
This change fixes GET request queries returning a 400 if a content_type header is supplied
Releases contributed by @vethan via #3452
This change fixes GET request queries returning a 400 if a content_type header is supplied
Contributed by Nathan John via PR #3452
Now you have the opportunity to specify parameters such as tags, route_class, deprecated, include_in_schema, etc:
One column per quarter.
This release adds support for using FastAPI APIRouter arguments in GraphQLRouter.
Now you have the opportunity to specify parameters such as tags, route_class,
deprecated, include_in_schema, etc:
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello World"
schema = strawberry.Schema(Query)
graphql_app = GraphQLRouter(schema, tags=["graphql"])
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
Releases contributed by @nparamonov via #3442
This releases fixes a bug where schema extensions where not running a LIFO order.
This releases fixes a bug where schema extensions where not running a LIFO order.
Releases contributed by @nrbnlulu via #3416
This releases fixes a bug where schema extensions where not running a LIFO order.
This release fixes a deprecation warning when using the Apollo Tracing Extension.
This release fixes a deprecation warning when using the Apollo Tracing Extension.
Releases contributed by @coady via #3410
This release fixes a deprecation warning when using the Apollo Tracing Extension.
This release adds support for using both Pydantic v1 and v2, when importing from pydantic.v1.
This release adds support for using both Pydantic v1 and v2, when importing from
pydantic.v1.
This is automatically detected and the correct version is used.
Releases contributed by @patrick91 via #3426
This release adds support for using both Pydantic v1 and v2, when importing from
pydantic.v1.
This is automatically detected and the correct version is used.
Contributed by Patrick Arminio via PR #3426
Nothing published for this version
This release adds support for Apollo Federation in the schema codegen. Now you can convert a schema like this:
This release adds support for Apollo Federation in the schema codegen. Now you can convert a schema like this:
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3",
import: ["@key", "@shareable"])
type Query {
me: User
}
type User @key(fields: "id") {
id: ID!
username: String! @shareable
}
to a Strawberry powered schema like this:
import strawberry
@strawberry.type
class Query:
me: User | None
@strawberry.federation.type(keys=["id"])
class User:
id: strawberry.ID
username: str = strawberry.federation.field(shareable=True)
schema = strawberry.federation.Schema(query=Query, enable_federation_2=True)
By running the following command:
strawberry schema-codegen example.graphql
Releases contributed by @patrick91 via #3417
This release adds support for Apollo Federation in the schema codegen. Now you can convert a schema like this:
extend schema
@link ( url : "https://specs.apollo.dev/federation/v2.3" ,
import : [ "@key" , "@shareable" ])
type Query {
me : User
}
type User @key ( fields : "id" ) {
id : ID !
username : String ! @shareable
}
to a Strawberry powered schema like this:
import strawberry
@strawberry.type
class Query :
me: User | None
@strawberry.federation.type ( keys =[ "id" ])
class User :
id : strawberry.ID
username: str = strawberry.federation.field( shareable = True )
schema = strawberry.federation.Schema( query =Query, enable_federation_2 = True )
By running the following command:
Terminal window
strawberry schema-codegen example.graphql
Contributed by Patrick Arminio via PR #3417
This release adds support for Apollo Federation v2.7 which includes the @authenticated, @requiresScopes, @policy directives, as well as the label argu
This release adds support for Apollo Federation v2.7 which includes the @authenticated, @requiresScopes, @policy directives, as well as the label argument for @override.
As usual, we have first class support for them in the strawberry.federation namespace, here's an example:
from strawberry.federation.schema_directives import Override
@strawberry.federation.type(
authenticated=True,
policy=[["client", "poweruser"], ["admin"]],
requires_scopes=[["client", "poweruser"], ["admin"]],
)
class Product:
upc: str = strawberry.federation.field(
override=Override(override_from="mySubGraph", label="percent(1)")
)
Releases contributed by @TygerTaco via #3420
This release properly allows passing one argument to the Info class.
This release properly allows passing one argument to the Info class.
This is now fully supported:
import strawberry
from typing import TypedDict
class Context(TypedDict):
user_id: str
@strawberry.type
class Query:
@strawberry.field
def info(self, info: strawberry.Info[Context]) -> str:
return info.context["user_id"]
Releases contributed by @patrick91 via #3419
This release properly allows passing one argument to the Info class.
This is now fully supported:
import strawberry
from typing import TypedDict
class Context(TypedDict):
user_id: str
@strawberry.type
class Query:
@strawberry.field
def info(self, info: strawberry.Info[Context]) -> str:
return info.context["user_id"]
Contributed by Patrick Arminio via PR #3419
This release improves the Info type, by adding support for default TypeVars and by exporting it from the main module. This makes it easier to use Info
This release improves the Info type, by adding support for default TypeVars
and by exporting it from the main module. This makes it easier to use Info in
your own code, without having to import it from strawberry.types.info.
By exporting Info from the main module, now you can do the follwing:
import strawberry
@strawberry.type
class Query:
@strawberry.field
def info(self, info: strawberry.Info) -> str:
# do something with info
return "hello"
The Info type now has default TypeVars, so you can use it without having to
specify the type arguments, like we did in the example above. Make sure to use
the latest version of Mypy or Pyright for this. It also means that you can only
pass one value to it if you only care about the context type:
import strawberry
from .context import Context
@strawberry.type
class Query:
@strawberry.field
def info(self, info: strawberry.Info[Context]) -> str:
return info.context.user_id
Releases contributed by @patrick91 via #3418
Nothing published for this version
This release adds support to allow passing connection_params as dictionary to GraphQLWebsocketCommunicator class when testing channels integration
This release adds support to allow passing connection_params as dictionary to GraphQLWebsocketCommunicator class when testing channels integration
GraphQLWebsocketCommunicator(
application=application,
path="/graphql",
connection_params={"username": "strawberry"},
)
Releases contributed by @selvarajrajkanna via #3403
This release adds support to allow passing connection_params as dictionary to GraphQLWebsocketCommunicator class when testing channels integration
GraphQLWebsocketCommunicator(
application=application,
path="/graphql",
connection_params={"username": "strawberry"},
)
Contributed by selvarajrajkanna via PR #3403
Nothing published for this version
This releases updates the dependency of python-multipart to be at least 0.0.7 (which includes a security fix).
This releases updates the dependency of python-multipart to be at least 0.0.7 (which includes a security fix).
It also removes the upper bound for python-multipart so you can always install the latest version (if compatible) 😊
Releases contributed by @XChikuX via #3375
This releases updates the dependency of python-multipart to be at least 0.0.7 (which includes a security fix).
It also removes the upper bound for python-multipart so you can always install the latest version (if compatible) 😊
Improved error message when supplying in incorrect before or after argument with using relay and pagination.
Releases contributed by @sdobbelaere via #3361
This release adds support for litestar.
This release adds support for litestar.
import strawberry
from litestar import Request, Litestar
from strawberry.litestar 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: 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 = Litestar(
route_handlers=[GraphQLController],
)
Releases contributed by @gazorby via #3213
This release adds support for litestar.
import strawberry
from litestar import Request, Litestar
from strawberry.litestar 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 = Litestar(
route_handlers=[GraphQLController],
)
Contributed by Matthieu MN via PR #3213
This release fixes a small issue in the GraphQL Transport websocket where the connection would fail when receiving extra parameters in the payload sen
This release fixes a small issue in the GraphQL Transport websocket where the connection would fail when receiving extra parameters in the payload sent from the client.
This would happen when using Apollo Sandbox.
Releases contributed by @patrick91 via #3356
This release fixes a small issue in the GraphQL Transport websocket where the connection would fail when receiving extra parameters in the payload sent from the client.
This would happen when using Apollo Sandbox.
Contributed by Patrick Arminio via PR #3356
This release adds a new method get_fields on the Schema class. You can use get_fields to hide certain field based on some conditions, for example:
This release adds a new method get_fields on the Schema class.
You can use get_fields to hide certain field based on some conditions,
for example:
@strawberry.type
class User:
name: str
email: str = strawberry.field(metadata={"tags": ["internal"]})
@strawberry.type
class Query:
user: User
def public_field_filter(field: StrawberryField) -> bool:
return "internal" not in field.metadata.get("tags", [])
class PublicSchema(strawberry.Schema):
def get_fields(
self, type_definition: StrawberryObjectDefinition
) -> List[StrawberryField]:
return list(filter(public_field_filter, type_definition.fields))
schema = PublicSchema(query=Query)
The schema here would only have the name field on the User type.
Releases contributed by @patrick91 via #3274
Nothing published for this version
This hotfix enables permission extensions to be used with AsyncGenerators.
This hotfix enables permission extensions to be used with AsyncGenerators.
Releases contributed by @erikwrede via #3318
This hotfix enables permission extensions to be used with AsyncGenerators.
Contributed by Erik Wrede via PR #3318
Permissions classes now use a FieldExtension. The new preferred way to add permissions is to use the PermissionsExtension class:
Permissions classes now use a FieldExtension. The new preferred way to add permissions
is to use the PermissionsExtension class:
import strawberry
from strawberry.permission import PermissionExtension, BasePermission
class IsAuthorized(BasePermission):
message = "User is not authorized"
error_extensions = {"code": "UNAUTHORIZED"}
def has_permission(self, source, info, **kwargs) -> bool:
return False
@strawberry.type
class Query:
@strawberry.field(extensions=[PermissionExtension(permissions=[IsAuthorized()])])
def name(self) -> str:
return "ABC"
The old way of adding permissions using permission_classes is still
supported via the automatic addition of a PermissionExtension on the field.
Previously the kwargs argument keys for the has_permission method were
using camel casing (depending on your schema configuration), now they will
always follow the python name defined in your resolvers.
class IsAuthorized(BasePermission):
message = "User is not authorized"
def has_permission(
self, source, info, **kwargs: typing.Any
) -> bool: # pragma: no cover
# kwargs will have a key called "a_key"
# instead of `aKey`
return False
@strawberry.type
class Query:
@strawberry.field(permission_classes=[IsAuthorized])
def name(self, a_key: str) -> str: # pragma: no cover
return "Erik"
Using the new PermissionExtension API, permissions support even more features:
To return None or [] instead of raising an error, the fail_silently keyword
argument on PermissionExtension can be set to True.
Permissions will now automatically add pre-defined error extensions to the error, and
can use a custom GraphQLError class. This can be configured by modifying
the error_class and error_extensions attributes on the BasePermission class.
To customize the error handling, the on_unauthorized method on
the BasePermission class can be used. Further changes can be implemented by
subclassing the PermissionExtension class.
Permissions will automatically be added as schema directives to the schema. This
behavior can be altered by setting the add_directives to False
on PermissionExtension, or by setting the _schema_directive class attribute of the
permission to a custom directive.
Releases contributed by @erikwrede via #2570
Don't require NodeId annotation if resolve_id is overwritten on Node implemented types
Don't require NodeId annotation if resolve_id is overwritten on Node implemented types
Releases contributed by @devkral via #2844
Don't require NodeId annotation if resolve_id is overwritten on Node implemented types
Override encode_json() method in Django BaseView to use DjangoJSONEncoder
Override encode_json() method in Django BaseView to use DjangoJSONEncoder
Releases contributed by @noamsto via #3273
Override encode_json() method in Django BaseView to use DjangoJSONEncoder
Contributed by Noam Stolero via PR #3273
Fixed the base view so it uses parse_json when loading parameters from the query string instead of json.loads.
Fixed the base view so it uses parse_json when loading parameters from the query string instead of json.loads.
Releases contributed by @thearchitector via #3272
Fixed the base view so it uses parse_json when loading parameters from the query string instead of json.loads.
Contributed by Elias Gabriel via PR #3272
This release updates the Apollo Sandbox integration to all you to pass cookies to the GraphQL endpoint by enabling the Include cookes option in the Sa
This release updates the Apollo Sandbox integration to all you to pass cookies to the GraphQL endpoint by enabling the Include cookes option in the Sandbox settings.
Releases contributed by @patrick91 via #3278
This release updates the Apollo Sandbox integration to all you to pass cookies to the GraphQL endpoint by enabling the Include cookes option in the Sandbox settings.
Contributed by Patrick Arminio via PR #3278
Nothing published for this version
Improved error message when supplying GlobalID format that relates to another type than the query itself.
Improved error message when supplying GlobalID format that relates to another type than the query itself.
Releases contributed by @sdobbelaere via #3194
Improved error message when supplying GlobalID format that relates to another type than the query itself.
Adds an optional extensions parameter to strawberry.federation.field, with default value None. The key is passed through to strawberry.field, so the f
Adds an optional extensions parameter to strawberry.federation.field, with default value None. The key is passed through to strawberry.field, so the functionality is exactly as described here.
Example:
strawberry.federation.field(extensions=[InputMutationExtension()])
Releases contributed by @bricker via #3239
Adds an optional extensions parameter to strawberry.federation.field, with default value None. The key is passed through to strawberry.field, so the functionality is exactly as described here.
Example:
strawberry.federation.field(extensions=[InputMutationExtension()])
Contributed by Bryan Ricker via PR #3239
This release updates the GraphiQL packages to their latest versions:
This release updates the GraphiQL packages to their latest versions:
graphiql@3.0.9@graphiql/plugin-explorer@1.0.2Releases contributed by @rodrigofeijao via #3227
This release updates the GraphiQL packages to their latest versions:
graphiql@3.0.9@graphiql/plugin-explorer@1.0.2Contributed by Rodrigo Feijao via PR #3227
Nothing published for this version
Nothing published for this version
Nothing published for this version
Deprecations: This release deprecates the graphiql option in all HTTP integrations, in favour of graphql_ide, this allows us to only have one settings…
This release adds support in all all our HTTP integration for choosing between different GraphQL IDEs. For now we support GraphiQL (the default), Apollo Sandbox, and Pathfinder.
Deprecations: This release deprecates the graphiql option in all HTTP integrations,
in favour of graphql_ide, this allows us to only have one settings to change GraphQL ide,
or to disable it.
Here's a couple of examples of how you can use this:
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
from api.schema import schema
graphql_app = GraphQLRouter(schema, graphql_ide="apollo-sandbox")
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
from django.urls import path
from strawberry.django.views import GraphQLView
from api.schema import schema
urlpatterns = [
path("graphql/", GraphQLView.as_view(schema=schema, graphql_ide="pathfinder")),
]
Releases contributed by @patrick91 via #3209
Nothing published for this version
Nothing published for this version
Nothing published for this version
This release changes how we check for generic types. Previously, any type that had a generic typevar would be considered generic for the GraphQL schem
This release changes how we check for generic types. Previously, any type that had a generic typevar would be considered generic for the GraphQL schema, this would generate un-necessary types in some cases. Now, we only consider a type generic if it has a typevar that is used as the type of a field or one of its arguments.
For example the following type:
@strawberry.type
class Edge[T]:
cursor: strawberry.ID
some_interna_value: strawberry.Private[T]
Will not generate a generic type in the schema, as the typevar T is not used
as the type of a field or argument.
Releases contributed by @patrick91 via #3202
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
This release removes unused graphiql submodules for Flask, Quart and Sanic.
This release removes unused graphiql submodules for Flask, Quart and Sanic.
Releases contributed by @catwell via #3203
This release removes unused graphiql submodules for Flask, Quart and Sanic.
Contributed by Pierre Chapuis via PR #3203
This release fixes an issue that prevented the parser_cache extension to be used in combination with other extensions such as MaxTokensLimiter.
This release fixes an issue that prevented the parser_cache extension to be used in combination with
other extensions such as MaxTokensLimiter.
The following should work as expected now:
schema = strawberry.Schema(
query=Query, extensions=[MaxTokensLimiter(max_token_count=20), ParserCache()]
)
Releases contributed by @Dazix via #3170
This release fixes an issue that prevented the parser_cache extension to be used in combination with
other extensions such as MaxTokensLimiter.
The following should work as expected now:
schema = strawberry.Schema(
query=Query, extensions=[MaxTokensLimiter(max_token_count=20), ParserCache()]
)
Contributed by David Šanda via PR #3170
This release adds a Quart view.
This release adds a Quart view.
Releases contributed by @catwell via #3162
This release adds a Quart view.
Contributed by Pierre Chapuis via PR #3162
This release deprecates our SentryTracingExtension, as it is now incorporated directly into Sentry itself as of version 1.32.0. You can now directly i…
This release deprecates our SentryTracingExtension, as it is now incorporated directly into Sentry itself as of version 1.32.0. You can now directly instrument Strawberry with Sentry.
Below is the revised usage example:
import sentry_sdk
from sentry_sdk.integrations.strawberry import StrawberryIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
integrations=[
# make sure to set async_execution to False if you're executing
# GraphQL queries synchronously
StrawberryIntegration(async_execution=True),
],
traces_sample_rate=1.0,
)
Many thanks to @sentrivana for their work on this integration!
Releases contributed by @patrick91 via #3169
Nothing published for this version
Fix strawberry mypy plugin for pydantic v2
Fix strawberry mypy plugin for pydantic v2
Releases contributed by @Corentin-Br via #3159
Fix strawberry mypy plugin for pydantic v2
Contributed by Corentin-Br via PR #3159
Nothing published for this version
Remove stack_info from error log messages to not clutter error logging with unnecessary information.
Remove stack_info from error log messages to not clutter error logging with unnecessary information.
Releases contributed by @finsterwalder via #3143
Remove stack_info from error log messages to not clutter error logging with unnecessary information.
Contributed by Malte Finsterwalder via PR #3143
Add text/html content-type to chalice graphiql response
Add text/html content-type to chalice graphiql response
Releases contributed by @jpopesculian via #3137
Add text/html content-type to chalice graphiql response
Contributed by Julian Popescu via PR #3137
This release adds a new private hook in our HTTP views, it is called _handle_errors and it is meant to be used by Sentry (or other integrations) to ha
This release adds a new private hook in our HTTP views, it is called
_handle_errors and it is meant to be used by Sentry (or other integrations)
to handle errors without having to patch methods that could be overridden
by the users
Releases contributed by @patrick91 via #3127
This release adds a new private hook in our HTTP views, it is called
_handle_errors and it is meant to be used by Sentry (or other integrations)
to handle errors without having to patch methods that could be overridden
by the users
Contributed by Patrick Arminio via PR #3127
This release changes how we check for conflicting resolver arguments to exclude self from those checks, which were introduced on version 0.208.0.
This release changes how we check for conflicting resolver arguments to
exclude self from those checks, which were introduced on version 0.208.0.
It is a common pattern among integrations, such as the Django one, to
use root: Model in the resolvers for better typing inference.
Releases contributed by @bellini666 via #3131
This release changes how we check for conflicting resolver arguments to
exclude self from those checks, which were introduced on version 0.208.0.
It is a common pattern among integrations, such as the Django one, to
use root: Model in the resolvers for better typing inference.
Contributed by Thiago Bellini Ribeiro via PR #3131
Mark Django's asyncview as a coroutine using asgiref.sync.markcoroutinefunction to support using it with Python 3.12.
Mark Django's asyncview as a coroutine using asgiref.sync.markcoroutinefunction
to support using it with Python 3.12.
Releases contributed by @bellini666 via #3124
Mark Django's asyncview as a coroutine using asgiref.sync.markcoroutinefunction
to support using it with Python 3.12.
Contributed by Thiago Bellini Ribeiro via PR #3124
Nothing published for this version
Fix generation of input based on pydantic models using nested Annotated type annotations:
Fix generation of input based on pydantic models using nested Annotated type annotations:
import strawberry
from pydantic import BaseModel
class User(BaseModel):
age: Optional[Annotated[int, "metadata"]]
@strawberry.experimental.pydantic.input(all_fields=True)
class UserInput:
pass
Releases contributed by @gazorby via #3109
Fix generation of input based on pydantic models using nested Annotated type annotations:
import strawberry
from pydantic import BaseModel
class User(BaseModel):
age: Optional[Annotated[int, "metadata"]]
@strawberry.experimental.pydantic.input(all_fields=True)
class UserInput:
pass
Contributed by Matthieu MN via PR #3109
This release fixes an issue when trying to generate code from a schema that was using double quotes inside descriptions.
This release fixes an issue when trying to generate code from a schema that was using double quotes inside descriptions.
The following schema will now generate code correctly:
"""
A type of person or character within the "Star Wars" Universe.
"""
type Species {
"""
The classification of this species, such as "mammal" or "reptile".
"""
classification: String!
}
Releases contributed by @patrick91 via #3112
This release fixes an issue when trying to generate code from a schema that was using double quotes inside descriptions.
The following schema will now generate code correctly:
"""
A type of person or character within the "Star Wars" Universe.
"""
type Species {
"""
The classification of this species, such as "mammal" or "reptile".
"""
classification: String!
}
Contributed by Patrick Arminio via PR #3112
This release adds support for generating Strawberry types from SDL files. For example, given the following SDL file:
This release adds support for generating Strawberry types from SDL files. For example, given the following SDL file:
type Query {
user: User
}
type User {
id: ID!
name: String!
}
you can run
strawberry schema-codegen schema.graphql
to generate the following Python code:
import strawberry
@strawberry.type
class Query:
user: User | None
@strawberry.type
class User:
id: strawberry.ID
name: str
schema = strawberry.Schema(query=Query)
Releases contributed by @patrick91 via #3096
This release adds support for generating Strawberry types from SDL files. For example, given the following SDL file:
type Query {
user : User
}
type User {
id : ID !
name : String !
}
you can run
Terminal window
strawberry schema-codegen schema.graphql
to generate the following Python code:
import strawberry
@strawberry.type
class Query :
user: User | None
@strawberry.type
class User :
id : strawberry.ID
name: str
schema = strawberry.Schema( query =Query)
Contributed by Patrick Arminio via PR #3096
Adding support for additional pydantic built in types like EmailStr or PostgresDsn.
Adding support for additional pydantic built in types like EmailStr or PostgresDsn.
Releases contributed by @ppease via #3101
Adding support for additional pydantic built in types like EmailStr or PostgresDsn.
This release fixes an issue that would prevent using generics with unnamed unions, like in this example:
This release fixes an issue that would prevent using generics with unnamed unions, like in this example:
from typing import Generic, TypeVar, Union
import strawberry
T = TypeVar("T")
@strawberry.type
class Connection(Generic[T]):
nodes: list[T]
@strawberry.type
class Entity1:
id: int
@strawberry.type
class Entity2:
id: int
@strawberry.type
class Query:
entities: Connection[Union[Entity1, Entity2]]
Releases contributed by @patrick91 via #3099
This release fixes an issue that would prevent using generics with unnamed unions, like in this example:
from typing import Generic, TypeVar, Union
import strawberry
T = TypeVar("T")
@strawberry.type
class Connection(Generic[T]):
nodes: list[T]
@strawberry.type
class Entity1:
id: int
@strawberry.type
class Entity2:
id: int
@strawberry.type
class Query:
entities: Connection[Union[Entity1, Entity2]]
Contributed by Patrick Arminio via PR #3099
Your coding agent can read these notes before it upgrades. Set up the MCP server →