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
This release fixes a breaking internal error in mypy plugin for the following case.
- using positional arguments to pass a resolver for
strawberry.field()
orstrawberry.mutation()
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.
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
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: 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: Info):
# Arbitrary argument name when using `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
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.
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:
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
.
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
.
Contributed by Etty via PR #1959
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__
.
Contributed by Daniel Hahler via PR #1950
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 aStrawberrySchemaDirective
, which is now an internal type.
Contributed by Thiago Bellini Ribeiro via PR #1723
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 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.
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:
# some actual logic here
return strawberry_type(...)
return resolver
Contributed by Tim OSullivan via PR #1891
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:
- @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
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
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 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.
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
Contributed by James Chua via PR #1832
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.
@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 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
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
Contributed by Marco Acierno via PR #1811
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
-
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 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
This release fixes a bug in the codegen that marked optional unions as non optional.
Contributed by Patrick Arminio via PR #1806
This release adds support for passing json_encoder
and json_dumps_params
to Sanic's view.
from strawberry.sanic.views import GraphQLView
from api.schema import Schema
app = Sanic(__name__)
app.add_route(
GraphQLView.as_view(
schema=schema,
graphiql=True,
json_encoder=CustomEncoder,
json_dumps_params={},
),
"/graphql",
)
Contributed by Patrick Arminio via PR #1797
Allow use of AsyncIterator
and AsyncIterable
generics to annotate return
type of subscription resolvers.
Contributed by San Kilkis via PR #1771
Exeptions from handler functions in graphql_transport_ws are no longer incorrectly caught and classified as message parsing errors.
Contributed by KristjΓ‘n Valur JΓ³nsson via PR #1761
Drop support for Django < 3.2.
Contributed by Guillaume Andreu Sabater via PR #1787
This release adds support for aliased fields when doing codegen.
Contributed by Patrick Arminio via PR #1772
Add is_auto
utility for checking if a type is strawberry.auto
,
considering the possibility of it being a StrawberryAnnotation
or
even being used inside Annotated
.
Contributed by Thiago Bellini Ribeiro via PR #1721
This release moves the console plugin for the codegen command to be last one, allowing to run code before writing files to disk.
Contributed by Patrick Arminio via PR #1760
This release adds a python_type
to the codegen GraphQLEnum
class
to allow access to the original python enum when generating code
Contributed by Patrick Arminio via PR #1752
Fix an issue where there was no clean way to mark a Pydantic field as deprecated, add permission classes, or add directives. Now you can use the short field syntax to do all three.
import pydantic
import strawberry
class MyModel(pydantic.BaseModel):
age: int
name: str
@strawberry.experimental.pydantic.type(MyModel)
class MyType:
age: strawberry.auto
name: strawberry.auto = strawberry.field(
deprecation_reason="Because",
permission_classes=[MyPermission],
directives=[MyDirective],
)
Contributed by Matt Allen via PR #1748
This release adds a missing __init__.py
inside cli/commands
Contributed by Patrick Arminio via PR #1751
This release fixes an issue that prevented using generic types with interfaces.
Contributed by Patrick Arminio via PR #1701
This release fixes a couple of more issues with codegen:
- Adds support for boolean values in input fields
- Changes how we unwrap types in order to add full support for LazyTypes, Optionals and Lists
- Improve also how we generate types for unions, now we don't generate a Union type if the selection is for only one type
Contributed by Patrick Arminio via PR #1746
The return type annotation for DataLoader.load
and load_many
no longer
includes any exceptions directly returned by the load_fn
. The ability to
handle errors by returning them as elements from load_fn
is now documented too.
Contributed by Huon Wilson via PR #1737
This release add supports for LazyType
s in the codegen command
Contributed by Patrick Arminio via PR #1745
This release adds support for MyPy 0.941 under Python 3.10
Contributed by dependabot via PR #1728
This release adds an experimental codegen feature for queries. It allows to combine a graphql query and Strawberry schema to generate Python types or TypeScript types.
You can use the following command:
strawberry codegen --schema schema --output-dir ./output -p python query.graphql
to generate python types that correspond to your GraphQL query.
Contributed by Patrick Arminio via PR #1655
This release makes StrawberryOptional and StrawberryList hashable, allowing to use strawberry types with libraries like dacite and dataclasses_json.
Contributed by Patrick Arminio via PR #1726
Add support for postponed evaluation of annotations
(PEP-563) to strawberry.Private
annotated fields.
This release fixes Issue #1586 using schema-conversion time filtering of
strawberry.Private
fields for PEP-563. This means the following is now
supported:
@strawberry.type
class Query:
foo: "strawberry.Private[int]"
Forward references are supported as well:
from __future__ import annotations
from dataclasses import dataclass
@strawberry.type
class Query:
private_foo: strawberry.Private[SensitiveData]
@strawberry.field
def foo(self) -> int:
return self.private_foo.visible
@dataclass
class SensitiveData:
visible: int
not_visible int
Contributed by San Kilkis via PR #1684
This PR improves the support for scalars when using MyPy.
Contributed by Patrick Arminio via PR #1205
Added the response object to get_context
on the flask
view. This means that in fields, something like this can be used;
@strawberry.field
def response_check(self, info: Info) -> bool:
response: Response = info.context["response"]
response.status_code = 401
return True
This release adds support for graphql-transport-ws
single result operations.
Single result operations allow clients to execute queries and mutations over an existing WebSocket connection.
Contributed by Jonathan Ehwald PR #1698
Change strawberry.auto
to be a type instead of a sentinel.
This not only removes the dependency on sentinel from the project, but also fixes
some related issues, like the fact that only types can be used with Annotated
.
Also, custom scalars will now trick static type checkers into thinking they
returned their wrapped type. This should fix issues with pyright 1.1.224+ where
it doesn't allow non-type objects to be used as annotations for dataclasses and
dataclass-alike classes (which is strawberry's case). The change to strawberry.auto
also fixes this issue for it.
Contributed by Thiago Bellini Ribeiro PR #1690
This release adds support for flask 2.x and also relaxes the requirements for Django, allowing to install newer version of Django without having to wait for Strawberry to update its supported dependencies list.
Contributed by Guillaume Andreu Sabater PR #1687
This fixes the schema printer to add support for schema directives on input types.
Contributed by Patrick Arminio PR #1697
This release fixed a false positive deprecation warning related to our AIOHTTP class based view.
Contributed by Jonathan Ehwald PR #1691
This release adds the following scalar types:
JSON
Base16
Base32
Base64
they can be used like so:
from strawberry.scalar import Base16, Base32, Base64, JSON
@strawberry.type
class Example:
a: Base16
b: Base32
c: Base64
d: JSON
Contributed by Paulo Costa PR #1647
Adds support for converting pydantic conlist. Note that constraint is not enforced in the graphql type. Thus, we recommend always working on the pydantic type such that the validation is enforced.
import strawberry
from pydantic import BaseModel, conlist
class Example(BaseModel):
friends: conlist(str, min_items=1)
@strawberry.experimental.pydantic.input(model=Example, all_fields=True)
class ExampleGQL:
...
@strawberry.type
class Query:
@strawberry.field()
def test(self, example: ExampleGQL) -> None:
# friends may be an empty list here
print(example.friends)
# calling to_pydantic() runs the validation and raises
# an error if friends is empty
print(example.to_pydantic().friends)
schema = strawberry.Schema(query=Query)
The converted graphql type is
input ExampleGQL {
friends: [String!]!
}
Contributed by James Chua PR #1656
This release wasn't published on PyPI
This release updates graphql-core
to 3.2.0
Make sure you take a look at graphql-core
's release notes
for any potential breaking change that might affect you if you're importing things
from the graphql
package directly.
Contributed by Patrick Arminio PR #1601
Support "void" functions
It is now possible to have a resolver that returns "None". Strawberry will automatically assign the new Void
scalar in the schema
and will always send null
in the response
@strawberry.type
class Mutation:
@strawberry.field
def do_something(self, arg: int) -> None:
return
results in this schema:
type Mutation {
doSomething(arg: Int!): Void
}
Contributed by Paulo Costa PR #1648
Add better support for custom Pydantic conversion logic and standardize the
behavior when not using strawberry.auto
as the type.
See https://strawberry.rocks/docs/integrations/pydantic#custom-conversion-logic for details and examples.
Note that this release fixes a bug related to Pydantic aliases in schema
generation. If you have a field with the same name as an aliased Pydantic field
but with a different type than strawberry.auto
, the generated field will now
use the alias name. This may cause schema changes on upgrade in these cases, so
care should be taken. The alias behavior can be disabled by setting the
use_pydantic_alias
option of the decorator to false.
Contributed by Matt Allen PR #1629
Adds support for use_pydantic_alias
parameter in pydantic model conversion.
Decides if the all the GraphQL field names for the generated type should use the alias name or not.
from pydantic import BaseModel, Field
import strawberry
class UserModel(BaseModel):
id: int = Field(..., alias="my_alias_name")
@strawberry.experimental.pydantic.type(
UserModel, use_pydantic_alias=False
)
class User:
id: strawberry.auto
If use_pydantic_alias
is False
, the GraphQL type User will use id
for the name of the id
field coming from the Pydantic model.
type User {
id: Int!
}
With use_pydantic_alias
set to True
(the default behaviour) the GraphQL type user will use myAliasName
for the id
field coming from the Pydantic models (since the field has a alias
specified`)
type User {
myAliasName: Int!
}
use_pydantic_alias
is set to True
for backwards compatibility.
Contributed by James Chua PR #1546
This release adds compatibility with uvicorn 0.17
Contributed by dependabot PR #1627
This release fixes an issue with FastAPI context dependency injection that causes class-based custom contexts to no longer be permitted.
Contributed by Tommy Smith PR #1564
This release fixes an issue with the name generation for nested generics, the following:
T = TypeVar("T")
K = TypeVar("K")
V = TypeVar("V")
@strawberry.type
class Value(Generic[T]):
value: T
@strawberry.type
class DictItem(Generic[K, V]):
key: K
value: V
@strawberry.type
class Query:
d: Value[List[DictItem[int, str]]]
now yields the correct schema:
type IntStrDictItem {
key: Int!
value: String!
}
type IntStrDictItemListValue {
value: [IntStrDictItem!]!
}
type Query {
d: IntStrDictItemListValue!
}
Contributed by Patrick Arminio PR #1621
Fix bug #1504 in the Pydantic integration, where it was impossible to define both an input and output type based on the same Pydantic base class.
Contributed by Matt Allen PR #1592
Adds to_pydantic
and from_pydantic
type hints for IDE support.
Adds mypy extension support as well.
from pydantic import BaseModel
import strawberry
class UserPydantic(BaseModel):
age: int
@strawberry.experimental.pydantic.type(UserPydantic)
class UserStrawberry:
age: strawberry.auto
reveal_type(UserStrawberry(age=123).to_pydantic())
Mypy will infer the type as "UserPydantic". Previously it would be "Any"
Contributed by James Chua PR #1544
This release replaces cached_property
with backports.cached_property
to improve
the typing of the library.
Contributed by Rishi Kumar Ray PR #1582
Improve typing of @strawberry.enum()
by:
- Using a
TypeVar
bound onEnumMeta
instead ofEnumMeta
, which allows type-checkers (like pyright) to detect the fields of the enum being decorated. For example, for the following enum:
@strawberry.enum
class IceCreamFlavour(Enum):
VANILLA = "vanilla"
STRAWBERRY = "strawberry"
CHOCOLATE = "chocolate"
Prior to this change, pyright would complain if you tried to access
IceCreamFlavour.VANILLA
, since the type information of IceCreamFlavour
was
being erased by the EnumMeta
typing .
- Overloading it so that type-checkers (like pyright) knows in what cases it
returns a decorator (when it's called with keyword arguments, e.g.
@strawberry.enum(name="IceCreamFlavor")
), versus when it returns the original enum type (without keyword arguments.
Contributed by Tim Joseph Dumol PR #1568
This release adds load_many
to DataLoader
.
Contributed by Silas Sewell PR #1528
This release adds deprecation_reason
support to arguments and mutations.
Contributed by Silas Sewell PR #1527
This release checks for AutoFieldsNotInBaseModelError when converting from pydantic models. It is raised when strawberry.auto is used, but the pydantic model does not have the particular field defined.
class User(BaseModel):
age: int
@strawberry.experimental.pydantic.type(User)
class UserType:
age: strawberry.auto
password: strawberry.auto
Previously no errors would be raised, and the password field would not appear on graphql schema. Such mistakes could be common during refactoring. Now, AutoFieldsNotInBaseModelError is raised.
Contributed by James Chua PR #1551
Fixes TypeError when converting a pydantic BaseModel with NewType field
Contributed by James Chua PR #1547
This release allows setting http headers and custom http status codes with FastAPI GraphQLRouter.
Contributed by David NΔmec PR #1537
Fix compatibility with Sanic 21.12
Contributed by Artjoms Iskovs PR #1520
Add support for piping StrawberryUnion
and None
when annotating types.
For example:
@strawberry.type
class Cat:
name: str
@strawberry.type
class Dog:
name: str
Animal = strawberry.union("Animal", (Cat, Dog))
@strawberry.type
class Query:
animal: Animal | None # This line no longer triggers a TypeError
Contributed by Yossi Rozantsev PR #1540
This release fixes the conversion of pydantic models with a default_factory field.
Contributed by James Chua PR #1538
This release allows conversion of pydantic models with mutable default fields into strawberry types. Also fixes bug when converting a pydantic model field with default_factory. Previously it would raise an exception when fields with a default_factory were declared before fields without defaults.
Contributed by James Chua PR #1491
This release updates the Decimal and UUID scalar parsers to exclude the original_error exception and format the error message similar to other builtin scalars.
Contributed by Silas Sewell PR #1507
Fix mypy plugin crushes when _get_type_for_expr is used on var nodes
Contributed by Andrii Kohut PR #1513
This release fixes a bug in the annotation parser that prevents using strict typinh for Optional arguments which have their default set to UNSET.
Contributed by Sarah Henkens PR #1467
This release adds support for mypy 0.920.
Contributed by Yossi Rozantsev PR #1503
This releases fixes a bug with the opentracing extension where the tracer wasn't replacing the field name correctly.
This release modifies the internal utility function await_maybe
towards updating mypy to 0.920.
Contributed by Yossi Rozantsev PR #1505
Change context_getter
in strawberry.fastapi.GraphQLRouter
to merge, rather than overwrite, default and custom getters.
This mean now you can always access the request
instance from info.context
, even when using
a custom context getter.
Contributed by Tommy Smith PR #1494
This release changes when we fetch the event loop in dataloaders to prevent using the wrong event loop in some occasions.
Contributed by Patrick Arminio PR #1498
This release fixes an issue that prevented from lazily importing enum types using LazyType.
Contributed by Patrick Arminio PR #1501
This release allows running strawberry as a script, for example, you can start the debug server with the following command:
python -m strawberry server schema
Contributed by YogiLiu PR #1481
This release adds support for uvicorn 0.16
Contributed by dependabot PR #1487
This fixes the previous release that introduced a direct dependency on Django.
Contributed by Guillaume Andreu Sabater PR #1489
This release adds support for Django 4.0
Contributed by Guillaume Andreu Sabater PR #1484
This release operation_type
to the ExecutionContext
type that is available
in extensions. It also gets the operation_name
from the query if one isn't
provided by the client.
Contributed by Jonathan Kim PR #1286
This release adds support for passing json_encoder
and json_dumps_params
to Django JsonResponse
via a view.
from json import JSONEncoder
from django.urls import path
from strawberry.django.views import AsyncGraphQLView
from .schema import schema
# Pass the JSON params to `.as_view`
urlpatterns = [
path(
"graphql",
AsyncGraphQLView.as_view(
schema=schema,
json_encoder=JSONEncoder,
json_dumps_params={"separators": (",", ":")},
),
),
]
# β¦ or set them in a custom view
class CustomAsyncGraphQLView(AsyncGraphQLView):
json_encoder = JSONEncoder
json_dumps_params = {"separators": (",", ":")}
Contributed by Illia Volochii PR #1472
Fix cross-module type resolving for fields and resolvers
The following two issues are now fixed:
-
A field with a generic (typeless) resolver looks up the type relative to the resolver and not the class the field is defined in. (#1448)
-
When inheriting fields from another class the origin of the fields are set to the inheriting class and not the class the field is defined in.
Both these issues could lead to a rather undescriptive error message:
TypeError: (...) fields cannot be resolved. Unexpected type 'None'
Contributed by Michael P. Jung PR #1449
This releases fixes an issue where you were not allowed
to return a non-strawberry type for fields that return
an interface. Now this works as long as each type
implementing the interface implements an is_type_of
classmethod. Previous automatic duck typing on types
that implement an interface now requires explicit
resolution using this classmethod.
This release adds a GraphQLTestClient
. It hides the http request's details and asserts that there are no errors in the response (you can always disable this behavior 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 django.test.client import Client
from strawberry.django.test import GraphQLTestClient
@pytest.fixture()
def graphql_client():
yield GraphQLTestClient(Client())
And use it everywere in your test methods
def test_strawberry(graphql_client):
query = """
query Hi($name: String!) {
hi(name: $name)
}
"""
result = graphql_client.query(query, variables={"name": "Marcotte"})
assert result.data == {"hi": "Hi Marcotte!"}
It can be used to test the file uploads as well
from django.core.files.uploadedfile import SimpleUploadedFile
def test_upload(graphql_client):
f = SimpleUploadedFile("file.txt", b"strawberry")
query = """
mutation($textFile: Upload!) {
readText(textFile: $textFile)
}
"""
response = graphql_client.query(
query=query,
variables={"textFile": None},
files={"textFile": f},
)
assert response.data["readText"] == "strawberry"
This release fixes an issue that prevented using enums as arguments for generic types inside unions.
Contributed by Patrick Arminio PR #1463
This release fixes the message of InvalidFieldArgument
to properly show the field's name in the error message.
This release fixes an issue that prevented using classmethod
s and staticmethod
s as resolvers
import strawberry
@strawberry.type
class Query:
@strawberry.field
@staticmethod
def static_text() -> str:
return "Strawberry"
@strawberry.field
@classmethod
def class_name(cls) -> str:
return cls.__name__
Contributed by Illia Volochii PR #1430
This release improves type checking support for strawberry.union
and now allows
to use unions without any type issue, like so:
@strawberry.type
class User:
name: str
@strawberry.type
class Error:
message: str
UserOrError = strawberry.union("UserOrError", (User, Error))
x: UserOrError = User(name="Patrick")
Contributed by Patrick Arminio PR #1438
Fix init of Strawberry types from pydantic by skipping fields that have resolvers.
This release fixes an issubclass test failing for Literal
s in the experimental pydantic
integration.
This release changes how strawberry.Private
is implemented to
improve support for type checkers.
Contributed by Patrick Arminio PR #1437
This release adds support for AWS Chalice. A framework for deploying serverless applications using AWS.
A view for aws chalice has been added to the strawberry codebase. This view embedded in a chalice app allows anyone to get a GraphQL API working and hosted on AWS in minutes using a serverless architecture.
Contributed by Mark Sheehan PR #923
This release fixes the naming generation of generics when passing a generic type to another generic, like so:
@strawberry.type
class Edge(Generic[T]):
node: T
@strawberry.type
class Connection(Generic[T]):
edges: List[T]
Connection[Edge[int]]
Contributed by Patrick Arminio PR #1436
This releases updates the typing_extension
dependency to latest version.
Contributed by dependabot PR #1417
This release renames an internal exception from NotAnEnum
to ObjectIsNotAnEnumError
.
Contributed by Patrick Arminio PR #1317
This release changes how we handle GraphQL names. It also introduces a new
configuration option called name_converter
. This option allows you to specify
a custom NameConverter
to be used when generating GraphQL names.
This is currently not documented because the API will change slightly in future as we are working on renaming internal types.
This release also fixes an issue when creating concrete types from generic when passing list objects.
Contributed by Patrick Arminio PR #1394
This release fixes our MyPy plugin and re-adds support for typechecking classes created with the apollo federation decorator.
Contributed by Patrick Arminio PR #1414
Add on_executing_*
hooks to extensions to allow you to override the execution phase of a GraphQL operation.
Contributed by Jonathan Kim PR #1400
This release fixes an issue with schema directives not being printed correctly.
Contributed by Patrick Arminio PR #1376
This release introduces initial support for schema directives and updates the federation support to use that.
Full support will be implemented in future releases.
Contributed by Patrick Arminio PR #815
Field definition uses output of default_factory
as the GraphQL default_value
.
a_field: list[str] = strawberry.field(default_factory=list)
aField: [String!]! = []
Contributed by A. Coady PR #1371
This release fixed the typing support for Pyright.
Contributed by Patrick Arminio PR #1363
This release adds an extra dependency for FastAPI to prevent it being downloaded even when not needed.
To install Strawberry with FastAPI support you can do:
pip install 'strawberry-graphql[fastapi]'
Contributed by Patrick Arminio PR #1366
This release fixes the merge_types
type signature.
Contributed by Guillaume Andreu Sabater PR #1348
This release adds support for FastAPI integration using APIRouter.
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)
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
Contributed by JiΕΓ BireΕ‘ PR #1291
Improve help texts for CLI to work better on ZSH.
Contributed by Magnus Markling PR #1360
Errors encountered in subscriptions will now be logged to the strawberry.execution
logger as errors encountered in Queries and Mutations are. <3
Contributed by Michael Ossareh PR #1316
Add logic to convert arguments of type LazyType.
Contributed by Luke Murray PR #1350
This release fixes a bug where passing scalars in the scalar_overrides
parameter wasn't being applied consistently.
Contributed by Jonathan Kim PR #1212
Pydantic fields' description
are now copied to the GraphQL schema
import pydantic
import strawberry
class UserModel(pydantic.BaseModel):
age: str = pydantic.Field(..., description="Description")
@strawberry.experimental.pydantic.type(UserModel)
class User:
age: strawberry.auto
type User {
"""Description"""
age: String!
}
Contributed by Guillaume Andreu Sabater PR #1332
We now run our tests against Windows during CI!
Contributed by Michael Ossareh PR #1321
Add a shortcut to merge queries, mutations. E.g.:
import strawberry
from strawberry.tools import merge_types
@strawberry.type
class QueryA:
...
@strawberry.type
class QueryB:
...
ComboQuery = merge_types("ComboQuery", (QueryB, QueryA))
schema = strawberry.Schema(query=ComboQuery)
Contributed by Alexandru MΔrΔΘteanu PR #1273
Makes the GraphQLSchema instance accessible from resolvers via the info
parameter.
Contributed by Aryan Iyappan PR #1311
Fix bug where errors thrown in the on_parse_* extension hooks were being swallowed instead of being propagated.
Contributed by Jonathan Kim PR #1324
Adds support for the auto
type annotation described in #1192 to the Pydantic
integration, which allows a user to define the list of fields without having to
re-specify the type themselves. This gives better editor and type checker
support. If you want to expose every field you can instead pass
all_fields=True
to the decorators and leave the body empty.
import pydantic
import strawberry
from strawberry.experimental.pydantic import auto
class User(pydantic.BaseModel):
age: int
password: str
@strawberry.experimental.pydantic.type(User)
class UserType:
age: auto
password: auto
Contributed by Matt Allen PR #1280
This release adds a safety check on strawberry.type
, strawberry.input
and
strawberry.interface
decorators. When you try to use them with an object that is not a
class, you will get a nice error message:
strawberry.type can only be used with classes
Contributed by dependabot PR #1278
Add Starlette
to the integrations section on the documentation.
Contributed by Marcelo Trylesinski PR #1287
This release add support for the upcoming python 3.10 and it adds support for the new union syntax, allowing to declare unions like this:
import strawberry
@strawberry.type
class User:
name: str
@strawberry.type
class Error:
code: str
@strawberry.type
class Query:
find_user: User | Error
Contributed by Patrick Arminio PR #719
This release adds support for the graphql-transport-ws
GraphQL over WebSocket
protocol. Previously Strawberry only supported the legacy graphql-ws
protocol.
Developers can decide which protocols they want to accept. The following example shows how to do so using the ASGI integration. By default, both protocols are accepted. Take a look at our GraphQL subscription documentation to learn more.
from strawberry.asgi import GraphQL
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL
from api.schema import schema
app = GraphQL(schema, subscription_protocols=[GRAPHQL_TRANSPORT_WS_PROTOCOL])
Contributed by Jonathan Ehwald PR #1256
Nests the resolver under the correct span; prior to this change your span would have looked something like:
GraphQL Query
GraphQL Parsing
GraphQL Validation
my_resolver
my_span_of_interest #1
my_sub_span_of_interest #2
After this change you'll have:
GraphQL Query
GraphQL Parsing
GraphQL Validation
GraphQL Resolving: my_resolver
my_span_of_interest #1
my_sub_span_of_interest #2
Contributed by Michael Ossareh PR #1281
Enhances strawberry.extensions.tracing.opentelemetry to include spans for the Parsing and Validation phases of request handling. These occur before your resovler is called, so now you can see how much time those phases take up!
Contributed by Michael Ossareh PR #1274
Fix extensions
argument type definition on strawberry.Schema
Contributed by Guillaume Andreu Sabater PR #1276
This release introduces some brand new extensions to help improve the performance of your GraphQL server:
ParserCache
- Cache the parsing of a query in memoryValidationCache
- Cache the validation step of execution
For complicated queries these 2 extensions can improve performance by over 50%!
Example:
import strawberry
from strawberry.extensions import ParserCache, ValidationCache
schema = strawberry.Schema(
Query,
extensions=[
ParserCache(),
ValidationCache(),
]
)
This release also removes the validate_queries
and validation_rules
parameters on the schema.execute*
methods in favour of using the
DisableValidation
and AddValidationRule
extensions.
Contributed by Jonathan Kim PR #1196
This release adds support for Sanic v21
Contributed by dependabot PR #1105
Fixes returning "500 Internal Server Error" responses to requests with malformed json when running with ASGI integration.
Contributed by Olesia Grydzhuk PR #1260
This release adds python_name
to the Info
type.
Contributed by Joe Freeman PR #1257
Fix the Pydantic conversion method for Enum values, and add a mechanism to specify an interface type when converting from Pydantic. The Pydantic interface is really a base dataclass for the subclasses to extend. When you do the conversion, you have to use strawberry.experimental.pydantic.interface
to let us know that this type is an interface. You also have to use your converted interface type as the base class for the sub types as normal.
Contributed by Matt Allen PR #1241
Fixes a bug with the selected_fields
property on info
when an operation
variable is not defined.
Issue #1248.
Contributed by Jonathan Kim PR #1249
Fix issues (#1158 and #1104) where Generics using LazyTypes and Enums would not be properly resolved
These now function as expected:
T = TypeVar("T")
@strawberry.enum
class VehicleMake(Enum):
FORD = 'ford'
TOYOTA = 'toyota'
HONDA = 'honda'
@strawberry.type
class GenericForEnum(Generic[T]):
generic_slot: T
@strawberry.type
class SomeType:
field: GenericForEnum[VehicleMake]
another_file.py
@strawberry.type
class TypeFromAnotherFile:
something: bool
this_file.py
T = TypeVar("T")
@strawberry.type
class GenericType(Generic[T]):
item: T
@strawberry.type
class RealType:
lazy: GenericType[LazyType["TypeFromAnotherFile", "another_file.py"]]
Contributed by ignormies PR #1235
This release adds fragment and input variable information to the
selected_fields
attribute on the Info
object.
Contributed by Jonathan Kim PR #1213
Fixes a bug in the Pydantic conversion code around Union
values.
Contributed by Matt Allen PR #1231
Fixes a bug in the export-schema
command around the handling of local modules.
Contributed by Matt Allen PR #1233
Fixes a bug in the Pydantic conversion code around complex Optional
values.
Contributed by Matt Allen PR #1229
This release adds a new exception called InvalidFieldArgument
which is raised when a Union or Interface is used as an argument type.
For example this will raise an exception:
import strawberry
@strawberry.type
class Noun:
text: str
@strawberry.type
class Verb:
text: str
Word = strawberry.union("Word", types=(Noun, Verb))
@strawberry.field
def add_word(word: Word) -> bool:
...
Contributed by Mohammad Hossein Yazdani PR #1222
Fix type resolution when inheriting from types from another module using deferred annotations.
Contributed by Daniel Bowring PR #1010
This release adds support for Pyright and Pylance, improving the integration with Visual Studio Code!
Contributed by Patrick Arminio PR #922
Change the version constraint of opentelemetry-sdk and opentelemetry-api to <2
Contributed by Michael Ossareh PR #1226
This release adds support for enabling subscriptions in GraphiQL
on Django by setting a flag subscriptions_enabled
on the BaseView class.
from strawberry.django.views import AsyncGraphQLView
from .schema import schema
urlpatterns = [path("graphql", AsyncGraphQLView.as_view(schema=schema, graphiql=True, subscriptions_enabled=True))]
This release fixes an issue with the MyPy plugin that prevented using
TextChoices from django in strawberry.enum
.
Contributed by Patrick Arminio PR #1202
This release improves how we deal with custom scalars. Instead of being global they are now scoped to the schema. This allows you to have multiple schemas in the same project with different scalars.
Also you can now override the built in scalars with your own custom
implementation. Out of the box Strawberry provides you with custom scalars for
common Python types like datetime
and Decimal
. If you require a custom
implementation of one of these built in scalars you can now pass a map of
overrides to your schema:
from datetime import datetime, timezone
import strawberry
EpochDateTime = strawberry.scalar(
datetime,
serialize=lambda value: int(value.timestamp()),
parse_value=lambda value: datetime.fromtimestamp(int(value), timezone.utc),
)
@strawberry.type
class Query:
@strawberry.field
def current_time(self) -> datetime:
return datetime.now()
schema = strawberry.Schema(
Query,
scalar_overrides={
datetime: EpochDateTime,
}
)
result = schema.execute_sync("{ currentTime }")
assert result.data == {"currentTime": 1628683200}
Contributed by Jonathan Kim PR #1147
This release allows to install Strawberry along side click
version 8.
Contributed by Patrick Arminio PR #1181
This release add full support for async directives and fixes and issue when using directives and async extensions.
@strawberry.type
class Query:
name: str = "Banana"
@strawberry.directive(
locations=[DirectiveLocation.FIELD], description="Make string uppercase"
)
async def uppercase(value: str):
return value.upper()
schema = strawberry.Schema(query=Query, directives=[uppercase])
Contributed by Patrick Arminio PR #1179
Fix issue where strawberry.Private
fields on converted Pydantic types were not added to the resulting dataclass.
Contributed by Paul Sud PR #1173
This releases fixes a MyPy issue that prevented from using types created with
create_type
as base classes. This is now allowed and doesn't throw any error:
import strawberry
from strawberry.tools import create_type
@strawberry.field
def name() -> str:
return "foo"
MyType = create_type("MyType", [name])
class Query(MyType):
...
Contributed by Patrick Arminio PR #1175
This release fixes an import error when trying to import create_type
without having opentelemetry
installed.
Contributed by Patrick Arminio PR #1171
This release adds support for the latest version of the optional opentelemetry dependency.
Contributed by Patrick Arminio PR #1170
This release adds support for the latest version of the optional opentelemetry dependency.
Contributed by Joe Freeman PR #1169
This release allows background tasks to be set with the ASGI integration. Tasks can be set on the response in the context, and will then get run after the query result is returned.
from starlette.background import BackgroundTask
@strawberry.mutation
def create_flavour(self, info: Info) -> str:
info.context["response"].background = BackgroundTask(...)
Contributed by Joe Freeman PR #1168
This release caches attributes on the Info
type which aren't delegated to the core info object.
Contributed by A. Coady PR #1167
This releases fixes an issue where you were not allowed to use duck typing and return a different type that the type declared on the field when the type was implementing an interface. Now this works as long as you return a type that has the same shape as the field type.
Contributed by Patrick Arminio PR #1150
This release improves execution performance significantly by lazy loading
attributes on the Info
type π
Contributed by Jonathan Kim PR #1165
This release adds support for asynchronous hooks to the Strawberry extension-system. All available hooks can now be implemented either synchronously or asynchronously.
It's also possible to mix both synchronous and asynchronous hooks within one extension.
from strawberry.extensions import Extension
class MyExtension(Extension):
async def on_request_start(self):
print("GraphQL request start")
def on_request_end(self):
print("GraphQL request end")
Contributed by Jonathan Ehwald PR #1142
This release refactors the reload feature of the built-in debug server. The refactor
made the debug server more responsive and allowed us to remove hupper
from the
dependencies.
Contributed by Jonathan Ehwald PR #1114
This releases pins graphql-core to only accept patch versions in order to prevent breaking changes since graphql-core doesn't properly follow semantic versioning.
Contributed by Jonathan Kim PR #1162
This release improves the default logging format for errors to include more information about the errors. For example it will show were an error was originated in a request:
GraphQL request:2:5
1 | query {
2 | example
| ^
3 | }
Contributed by Ivan Gonzalez PR #1152
This release adds support for asynchronous permission classes. The only difference to
their synchronous counterpart is that the has_permission
method is asynchronous.
from strawberry.permission import BasePermission
class IsAuthenticated(BasePermission):
message = "User is not authenticated"
async def has_permission(self, source, info, **kwargs):
return True
Contributed by Jonathan Ehwald PR #1125
Get a field resolver correctly when extending from a pydantic model
Contributed by Jonathan Kim PR #1116
This release adds asgi
as an extra dependencies group for Strawberry. Now
you can install the required dependencies needed to use Strawberry with
ASGI by running:
pip install 'strawberry[asgi]'
Contributed by A. Coady PR #1036
This releases adds selected_fields
on the info
objects and it
allows to introspect the fields that have been selected in a GraphQL
operation.
This can become useful to run optimisation based on the queried fields.
Contributed by A. Coady PR #874
This release adds a query depth limit validation rule so that you can guard against malicious queries:
import strawberry
from strawberry.schema import default_validation_rules
from strawberry.tools import depth_limit_validator
# Add the depth limit validator to the list of default validation rules
validation_rules = (
default_validation_rules + [depth_limit_validator(3)]
)
result = schema.execute_sync(
"""
query MyQuery {
user {
pets {
owner {
pets {
name
}
}
}
}
}
""",
validation_rules=validation_rules,
)
)
assert len(result.errors) == 1
assert result.errors[0].message == "'MyQuery' exceeds maximum operation depth of 3"
Contributed by Jonathan Kim PR #1021
Addition of app.add_websocket_route("/subscriptions", graphql_app)
to FastAPI example docs
Contributed by Anton Melser PR #1103
This release changes how we map Pydantic fields to types to allow using older version of Pydantic.
Contributed by Patrick Arminio PR #1071
This release makes the strawberry server
command inform the user about missing
dependencies required by the builtin debug server.
Also hupper
a package only used by said command has been made optional.
Contributed by Jonathan Ehwald PR #1107
Switch CDN used to load GraphQLi dependencies from jsdelivr.com to unpkg.com
Contributed by Tim Savage PR #1096
This release adds support for disabling auto camel casing. It does so by introducing a new configuration parameter to the schema.
You can use it like so:
@strawberry.type
class Query:
example_field: str = "Example"
schema = strawberry.Schema(
query=Query, config=StrawberryConfig(auto_camel_case=False)
)
Contributed by Patrick Arminio PR #798
Fix for regression when defining inherited types with explicit fields.
Contributed by A. Coady PR #1076
This releases improves the MyPy plugin to be more forgiving of settings like follow_imports = skip which would break the type checking.
This is a continuation of the previous release and fixes for type checking issues.
Contributed by Patrick Arminio PR #1078
This releases improves the MyPy plugin to be more forgiving of
settings like follow_imports = skip
which would break the
type checking.
Contributed by Patrick Arminio PR #1077
This release removes a TypeGuard
import to prevent errors
when using older versions of typing_extensions
.
Contributed by Patrick Arminio PR #1074
Refactor of the library's typing internals. Previously, typing was handled individually by fields, arguments, and objects with a hodgepodge of functions to tie it together. This change creates a unified typing system that the object, fields, and arguments each hook into.
Mainly replaces the attributes that were stored on StrawberryArgument and StrawberryField with a hierarchy of StrawberryTypes.
Introduces StrawberryAnnotation
, as well as StrawberryType
and some subclasses,
including StrawberryList
, StrawberryOptional
, and StrawberryTypeVar
.
This is a breaking change if you were calling the constructor for StrawberryField
,
StrawberryArgument
, etc. and using arguments such as is_optional
or child
.
@strawberry.field
no longer takes an argument called type_
. It instead takes a
StrawberryAnnotation
called type_annotation
.
Contributed by ignormies PR #906
This release fixes an issue with the federation printer that prevented using federation directives with types that were implementing interfaces.
This is now allowed:
@strawberry.interface
class SomeInterface:
id: strawberry.ID
@strawberry.federation.type(keys=["upc"], extend=True)
class Product(SomeInterface):
upc: str = strawberry.federation.field(external=True)
Contributed by Patrick Arminio PR #1068
This release changes our graphiql.html
template to use a specific version of js-cookie
to prevent a JavaScript error, see:
This release fixes a regression that broke strawberry-graphql-django.
Field.get_results
now always receives the info
argument.
Contributed by Lauri Hintsala PR #1047
This release only changes some internal code to make future improvements easier.
Contributed by Patrick Arminio PR #1044
Matching the behaviour of graphql-core
, passing an incorrect ISO string value for a Time, Date or DateTime scalar now raises a GraphQLError
instead of the original parsing error.
The GraphQLError
will include the error message raised by the string parser, e.g. Value cannot represent a DateTime: "2021-13-01T09:00:00". month must be in 1..12
Fixes #1022 by making starlette an optional dependency.
Contributed by Marcel Wiegand PR #1027
Add ability to specific the graphql name for a resolver argument. E.g.,
from typing import Annotated
import strawberry
@strawberry.input
class HelloInput:
name: str = "world"
@strawberry.type
class Query:
@strawberry.field
def hello(
self,
input_: Annotated[HelloInput, strawberry.argument(name="input")]
) -> str:
return f"Hi {input_.name}"
Contributed by Daniel Bowring PR #1024
This release fixes a bug that was preventing the use of an enum member as the default value for an argument.
For example:
@strawberry.enum
class IceCreamFlavour(Enum):
VANILLA = "vanilla"
STRAWBERRY = "strawberry"
CHOCOLATE = "chocolate"
PISTACHIO = "pistachio"
@strawberry.mutation
def create_flavour(
self, flavour: IceCreamFlavour = IceCreamFlavour.STRAWBERRY
) -> str:
return f"{flavour.name}"
Contributed by Jonathan Kim PR #1015
This release reverts the changes made in v0.65.4 that caused an issue leading to
circular imports when using the strawberry-graphql-django
extension package.
Contributed by Lauri Hintsala PR #1019
This release fixes the IDE integration where package strawberry.django
could not be find by some editors like vscode.
Contributed by Lauri Hintsala PR #994
This release fixes the ASGI subscription implementation by handling disconnecting clients properly.
Additionally, the ASGI implementation has been internally refactored to match the AIOHTTP implementation.
Contributed by Jonathan Ehwald PR #1002
This release fixes a bug in the subscription implementations that prevented clients from selecting one of multiple subscription operations from a query. Client sent messages like the following one are now handled as expected.
{
"type": "GQL_START",
"id": "DEMO",
"payload": {
"query": "subscription Sub1 { sub1 } subscription Sub2 { sub2 }",
"operationName": "Sub2"
}
}
Contributed by Jonathan Ehwald PR #1000
This release fixes the upload of nested file lists. Among other use cases, having an input type like shown below is now working properly.
import typing
import strawberry
from strawberry.file_uploads import Upload
@strawberry.input
class FolderInput:
files: typing.List[Upload]
Contributed by Jonathan Ehwald PR #989
This release extends the file upload support of all integrations to support the upload of file lists.
Here is an example how this would work with the ASGI integration.
import typing
import strawberry
from strawberry.file_uploads import Upload
@strawberry.type
class Mutation:
@strawberry.mutation
async def read_files(self, files: typing.List[Upload]) -> typing.List[str]:
contents = []
for file in files:
content = (await file.read()).decode()
contents.append(content)
return contents
Check out the documentation to learn how the same can be done with other integrations.
Contributed by Jonathan Ehwald PR #979
This release fixes that AIOHTTP subscription requests were not properly separated. This could lead to subscriptions terminating each other.
Contributed by Jonathan Ehwald PR #970
- Remove usages of
undefined
in favour ofUNSET
- Change the signature of
StrawberryField
to make it easier to instantiate directly. Also changedefault_value
argument todefault
- Rename
default_value
todefault
inStrawberryArgument
Contributed by Jonathan Kim PR #916
This release integrates the strawberry-graphql-django
package into Strawberry
core so that it's possible to use the Django extension package directly via the
strawberry.django
namespace.
You still need to install strawberry-graphql-django
if you want to use the
extended Django support.
See: https://github.com/strawberry-graphql/strawberry-graphql-django
Contributed by Lauri Hintsala PR #949
This release fixes that enum values yielded from async generators were not resolved properly.
Contributed by Jonathan Ehwald PR #969
This release fixes a max recursion depth error in the AIOHTTP subscription implementation.
Contributed by Jonathan Ehwald PR #966
This release adds an extensions field to the GraphQLHTTPResponse
type and also exposes it in the view's response.
This field gets populated by Strawberry extensions: https://strawberry.rocks/docs/guides/extensions#get-results
Add root_value
to ExecutionContext
type so that it can be accessed in
extensions.
Example:
import strawberry
from strawberry.extensions import Extension
class MyExtension(Extension):
def on_request_end(self):
root_value = self.execution_context.root_value
# do something with the root_value
Contributed by Jonathan Kim PR #959
New deployment process to release new Strawberry releases
This release adds extra values to the ExecutionContext object so that it can be
used by extensions and the Schema.process_errors
function.
The full ExecutionContext object now looks like this:
from graphql import ExecutionResult as GraphQLExecutionResult
from graphql.error.graphql_error import GraphQLError
from graphql.language import DocumentNode as GraphQLDocumentNode
@dataclasses.dataclass
class ExecutionContext:
query: str
context: Any = None
variables: Optional[Dict[str, Any]] = None
operation_name: Optional[str] = None
graphql_document: Optional[GraphQLDocumentNode] = None
errors: Optional[List[GraphQLError]] = None
result: Optional[GraphQLExecutionResult] = None
and can be accessed in any of the extension hooks:
from strawberry.extensions import Extension
class MyExtension(Extension):
def on_request_end(self):
result = self.execution_context.result
# Do something with the result
schema = strawberry.Schema(query=Query, extensions=[MyExtension])
Note: This release also removes the creation of an ExecutionContext object in the web
framework views. If you were relying on overriding the get_execution_context
function then you should change it to get_request_data
and use the
strawberry.http.parse_request_data
function to extract the pieces of data
needed from the incoming request.
This releases fixes an issue with the debug server that prevented the usage of dataloaders, see: strawberry-graphql#940
This release adds support for GraphQL subscriptions to the AIOHTTP integration. Subscription support works out of the box and does not require any additional configuration.
Here is an example how to get started with subscriptions in general. Note that by specification GraphQL schemas must always define a query, even if only subscriptions are used.
import asyncio
import typing
import strawberry
@strawberry.type
class Subscription:
@strawberry.subscription
async def count(self, target: int = 100) -> typing.AsyncGenerator[int, None]:
for i in range(target):
yield i
await asyncio.sleep(0.5)
@strawberry.type
class Query:
@strawberry.field
def _unused(self) -> str:
return ""
schema = strawberry.Schema(subscription=Subscription, query=Query)
Fix @requires(fields: ["email"])
and @provides(fields: ["name"])
usage on a Federation field
You can use @requires
to specify which fields you need to resolve a field
import strawberry
@strawberry.federation.type(keys=["id"], extend=True)
class Product:
id: strawberry.ID = strawberry.federation.field(external=True)
code: str = strawberry.federation.field(external=True)
@classmethod
def resolve_reference(cls, id: strawberry.ID, code: str):
return cls(id=id, code=code)
@strawberry.federation.field(requires=["code"])
def my_code(self) -> str:
return self.code
@provides
can be used to specify what fields are going to be resolved
by the service itself without having the Gateway to contact the external service
to resolve them.
This release adds support for the info param in resolve_reference:
@strawberry.federation.type(keys=["upc"])
class Product:
upc: str
info: str
@classmethod
def resolve_reference(cls, info, upc):
return Product(upc, info)
Note: resolver reference is used when using Federation, similar to Apollo server's __resolveReference
This release extends the strawberry server
command to allow the specification
of a schema symbol name within a module:
strawberry server mypackage.mymodule:myschema
The schema symbol name defaults to schema
making this change backwards compatible.
This release adds file upload support to the Sanic integration. No additional configuration is required to enable file upload support.
The following example shows how a file upload based mutation could look like:
import strawberry
from strawberry.file_uploads import Upload
@strawberry.type
class Mutation:
@strawberry.mutation
def read_text(self, text_file: Upload) -> str:
return text_file.read().decode()
This release adds an export-schema
command to the Strawberry CLI.
Using the command you can print your schema definition to your console.
Pipes and redirection can be used to store the schema in a file.
Example usage:
strawberry export-schema mypackage.mymodule:myschema > schema.graphql
This release fixes an issue that prevented using source
as name of an argument
This release adds an aiohttp integration for
Strawberry. The integration provides a GraphQLView
class which can be used to
integrate Strawberry with aiohttp:
import strawberry
from aiohttp import web
from strawberry.aiohttp.views import GraphQLView
@strawberry.type
class Query:
pass
schema = strawberry.Schema(query=Query)
app = web.Application()
app.router.add_route("*", "/graphql", GraphQLView(schema=schema))
This release adds a function called create_type
to create a Strawberry type from a list of fields.
import strawberry
from strawberry.tools import create_type
@strawberry.field
def hello(info) -> str:
return "World"
def get_name(info) -> str:
return info.context.user.name
my_name = strawberry.field(name="myName", resolver=get_name)
Query = create_type("Query", [hello, my_name])
schema = strawberry.Schema(query=Query)
This release fixes an issue when using nested lists, this now works properly:
def get_polygons() -> List[List[float]]:
return [[2.0, 6.0]]
@strawberry.type
class Query:
polygons: List[List[float]] = strawberry.field(resolver=get_polygons)
schema = strawberry.Schema(query=Query)
query = "{ polygons }"
result = schema.execute_sync(query, root_value=Query())
This release fixes support for generic types so that now we can also use generics for input types:
T = typing.TypeVar("T")
@strawberry.input
class Input(typing.Generic[T]):
field: T
@strawberry.type
class Query:
@strawberry.field
def field(self, input: Input[str]) -> str:
return input.field
This release fixes a bug that prevented from extending a generic type when passing a type, like here:
T = typing.TypeVar("T")
@strawberry.interface
class Node(typing.Generic[T]):
id: strawberry.ID
def _resolve(self) -> typing.Optional[T]:
return None
@strawberry.type
class Book(Node[str]):
name: str
@strawberry.type
class Query:
@strawberry.field
def books(self) -> typing.List[Book]:
return list()
Fix converting pydantic objects to strawberry types using from_pydantic
when having a falsy value like 0 or ''.
Add a process_errors
method to strawberry.Schema
which logs all exceptions during execution to a strawberry.execution
logger.
This release fixes the return type value from info argument of resolver.
This release improves Pydantic support to support default values and factories.
This release fixes the pydantic integration where you couldn't convert objects to pydantic instance when they didn't have a default value.
Add --app-dir CLI option to specify where to find the schema module to load when using the debug server.
For example if you have a schema module in a my_app package under ./src, then you can run the debug server with it using:
strawberry server --app-dir src my_app.schema
Add support for default
and default_factory
arguments in strawberry.field
@strawberry.type
class Droid:
name: str = strawberry.field(default="R2D2")
aka: List[str] = strawberry.field(default_factory=lambda: ["Artoo"])
Internal refactoring.
- Renamed
StrawberryArgument
toStrawberryArgumentAnnotation
- Renamed
ArgumentDefinition
toStrawberryArgument
- Renamed
ArgumentDefinition(type: ...)
argument toStrawberryArgument(type_: ...)
- Renamed
Fixed issue with django multipart/form-data uploads
Fix issue where StrawberryField.graphql_name would always be camelCased
This release fixes an issue with the generated __eq__
and __repr__
methods when defining
fields with resolvers.
This now works properly:
@strawberry.type
class Query:
a: int
@strawberry.field
def name(self) -> str:
return "A"
assert Query(1) == Query(1)
assert Query(1) != Query(2)
Gracefully handle user-induced subscription errors.
-
FieldDefinition
has been absorbed intoStrawberryField
and now no longer exists. -
FieldDefinition.origin_name
andFieldDefinition.name
have been replaced withStrawberryField.python_name
andStrawberryField.graphql_name
. This should help alleviate some backend confusion about which should be used for certain situations. -
strawberry.types.type_resolver.resolve_type
has been split intoresolve_type_argument
and_resolve_type
(for arguments) untilStrawberryType
is implemented to combine them back together. This was done to reduce the scope of this PR and defer changingArgumentDefinition
(futureStrawberryArgument
) until a different PR.
Note: The constructor signature for
StrawberryField
hastype_
as an argument instead oftype
as was the case forFieldDefinition
. This is done to prevent shadowing of builtins.
Note:
StrawberryField.name
still exists because of the way dataclassField
s work, but is an alias forStrawberryField.python_name
.
Include field_nodes
in Strawberry info object.
Change get_context
to be async for sanic integration
Configures GraphiQL to attach CSRF cookies as request headers sent to the GQL server.
Expose Strawberry Info object instead of GraphQLResolveInfo in resolvers
Django 3.2 support
Raise exception when un-serializable payload is provided to the Django view.
This release fixes a regression with the django sending the wrong content type.
This release updates get_context in the django integration to also receive a temporal response object that can be used to set headers, cookies and status code.
@strawberry.type
class Query:
@strawberry.field
def abc(self, info: Info) -> str:
info.context.response.status_code = 418
return "ABC"
This releases changes how we define resolvers internally, now we have one single resolver for async and sync code.
Fix bug when using arguments inside a type that uses typing.Generics
This releases updates the ASGI class to make it easier to override get_http_response
.
get_http_response
has been now removed from strawberry.asgi.http and been moved to be
a method on the ASGI class.
A new get_graphiql_response
method has been added to make it easier to provide a different GraphiQL interface.
This release updates get_context
in the asgi integration to also
receive a temporal response object that can be used to set headers
and cookies.
This release fixes a bug when using the debug server and upload a file
Fix DataLoader docs typo.
Added support for sanic webserver.
ExecutionResult
was erroneously defined twice in the repository. The entry in strawberry.schema.base
has been removed. If you were using it, switch to using
strawberry.types.ExecutionResult
instead:
from strawberry.types import ExecutionResult
Enable using .get for django context as well as for the square brackets notation.
Enable dot notation for django context request
Supporting multipart file uploads on Flask
Expose execution info under strawberry.types.Info
Fixes mypy failing when casting in enum decorator
Suggest installing the debug server on the getting started docs, so examples can work without import errors of uvicorn
Fix Generic name generation to use the custom name specified in Strawberry if available
@strawberry.type(name="AnotherName")
class EdgeName:
node: str
@strawberry.type
class Connection(Generic[T]):
edge: T
will result in AnotherNameConnection
, and not EdgeNameConnection
as before.
This release add the ability to disable query validation by setting
validate_queries
to False
import strawberry
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello"
schema = strawberry.Schema(Query, validate_queries=validate_queries)
This release adds support for MyPy==0.800
Fix for a duplicated input types error.
Internal codebase refactor. Clean up, consolidate, and standardize the conversion layer between Strawberry types and GraphQL Core types; with room for further future abstraction to support other GraphQL backends.
Improves typing when decorating an enum with kwargs like description and name. Adds more mypy tests.
This releases fixes a wrong dependency issue
Supporting multipart uploads as described here: https://github.com/jaydenseric/graphql-multipart-request-spec for ASGI.
Fix Strawberry to handle multiple subscriptions at the same time
Pass execution_context_class
to Schema creation
Add support for converting more pydantic types
- pydantic.EmailStr
- pydantic.AnyUrl
- pydantic.AnyHttpUrl
- pydantic.HttpUrl
- pydantic.PostgresDsn
- pydantic.RedisDsn
This releases fixes an issue where methods marked as field were removed from the class.
Validate the schema when it is created instead of at runtime.
This release adds support for strawberry.federation.field under mypy.
Creation of a [debug-server]
extra, which is required to get going quickly with this project!
pip install strawberry-graphql
Will now install the primary portion of of the framework, allowing you to build your GraphQL schema using the dataclasses pattern.
To get going quickly, you can install [debug-server]
which brings along a server which allows
you to develop your API dynamically, assuming your schema is defined in the app
module:
pip install 'strawberry-graphql[debug-server]'
strawberry server app
Typically, in a production environment, you'd want to bring your own server :)
This release fixes an issue when using unions inside generic types, this is now supported:
@strawberry.type
class Dog:
name: str
@strawberry.type
class Cat:
name: str
@strawberry.type
class Connection(Generic[T]):
nodes: List[T]
@strawberry.type
class Query:
connection: Connection[Union[Dog, Cat]]
This releases fixes an issue with Strawberry requiring Pydantic even when not used.
This release adds support for creating types from Pydantic models. Here's an example:
import strawberry
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel
class UserModel(BaseModel):
id: int
name = 'John Doe'
signup_ts: Optional[datetime] = None
friends: List[int] = []
@strawberry.experimental.pydantic.type(model=UserModel, fields=[
'id',
'name',
'friends'
])
class UserType:
pass
Add some checks to make sure the types passed to .union
are valid.
Fix issue preventing reusing the same resolver for multiple fields, like here:
def get_name(self) -> str:
return "Name"
@strawberry.type
class Query:
name: str = strawberry.field(resolver=get_name)
name_2: str = strawberry.field(resolver=get_name)
Another small improvement for mypy, this should prevent mypy from crashing when it can't find a type
This release fixes another issue with mypy where it wasn't able to identify strawberry fields. It also now knows that fields with resolvers aren't put in the init method of the class.
This release type improves support for strawberry.field in mypy,
now we don't get Attributes without a default cannot follow attributes with one
when using strawberry.field before a type without a default.
Bugfix to allow the use of UNSET
as a default value for arguments.
import strawberry
from strawberry.arguments import UNSET, is_unset
@strawberry.type
class Query:
@strawberry.field
def hello(self, name: Optional[str] = UNSET) -> str:
if is_unset(name):
return "Hi there"
return "Hi {name}"
schema = strawberry.Schema(query=Query)
result = schema.execute_async("{ hello }")
assert result.data == {"hello": "Hi there"}
result = schema.execute_async('{ hello(name: "Patrick" }')
assert result.data == {"hello": "Hi Patrick"}
SDL:
type Query {
hello(name: String): String!
}
This release improves mypy support for strawberry.field
- Completely revamped how resolvers are created, stored, and managed by
StrawberryField. Now instead of monkeypatching a
FieldDefinition
object onto the resolver function itself, all resolvers are wrapped inside of aStrawberryResolver
object with the useful properties. arguments.get_arguments_from_resolver
is now theStrawberryResolver.arguments
property- Added a test to cover a situation where a field is added to a StrawberryType
manually using
dataclasses.field
but not annotated. This was previously uncaught.
This release fixes an issue with forward types
This release adds a built-in dataloader. Example:
async def app():
async def idx(keys):
return keys
loader = DataLoader(load_fn=idx)
[value_a, value_b, value_c] = await asyncio.gather(
loader.load(1),
loader.load(2),
loader.load(3),
)
assert value_a == 1
assert value_b == 2
assert value_c == 3
Allow interfaces to implement other interfaces. This may be useful if you are using the relay pattern or if you want to model base interfaces that can be extended.
Example:
import strawberry
@strawberry.interface
class Error:
message: str
@strawberry.interface
class FieldError(Error):
message: str
field: str
@strawberry.type
class PasswordTooShort(FieldError):
message: str
field: str
fix: str
Produces the following SDL:
interface Error {
message: String!
}
interface FieldError implements Error {
message: String!
field: String!
}
type PasswordTooShort implements FieldError & Error {
message: String!
field: String!
fix: String!
}
Fix mypy plugin to handle bug where the types
argument to strawberry.union
is passed in as a keyword argument instead of a position one.
MyUnion = strawberry.union(types=(TypeA, TypeB), name="MyUnion")
This release adds a new AsyncGraphQLView for django.
Improve typing for field
and StrawberryField
.
This release disable implicit re-export of modules. This fixes Strawberry for you if you were using implicit_reexport = False
in your MyPy config.
This fixes the prettier pre-lint check.
Fix issue when using strawberry.enum(module.EnumClass)
in mypy
This release adds support to mark a field as deprecated via deprecation_reason
Set default value to null in the schema when it's set to None
Register UUID's as a custom scalar type instead of the ID type.
This release fixes a bug when returning list in async resolvers
This release improves how we check for enums
This release improves how we handle enum values when returning lists of enums.
This releases adds a workaround to prevent mypy from crashing in specific occasions
This release fixes an issue preventing to return enums in lists
This release improves support for strawberry.enums when type checking with mypy.
Fix ASGI view to call get_context
during a websocket request
Add support for adding a description to field arguments using the Annotated
type:
from typing import Annotated
@strawberry.type
class Query:
@strawberry.field
def user_by_id(id: Annotated[str, strawberry.argument(description="The ID of the user")]) -> User:
...
which results in the following schema:
type Query {
userById(
"""The ID of the user"""
id: String
): User!
}
Note: if you are not using Python v3.9 or greater you will need to import Annotated
from typing_extensions
This release adds support for using strawberry.enum as a function with MyPy, this is now valid typed code:
from enum import Enum
import strawberry
class IceCreamFlavour(Enum):
VANILLA = "vanilla"
STRAWBERRY = "strawberry"
CHOCOLATE = "chocolate"
Flavour = strawberry.enum(IceCreamFlavour)
Add __str__
to Schema
to allow printing schema sdl with str(schema)
Extend support for parsing isoformat datetimes,
adding a dependency on the dateutil
library.
For example: "2020-10-12T22:00:00.000Z"
can now be parsed as a datetime with a UTC timezone.
Add schema.introspect()
method to return introspection result of the schema.
This might be useful for tools like apollo codegen
or graphql-voyager
which
expect a full json representation of the schema
This releases adds a new extension for OpenTelemetry.
import asyncio
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
ConsoleSpanExporter,
SimpleExportSpanProcessor,
)
import strawberry
from strawberry.extensions.tracing import OpenTelemetryExtension
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
SimpleExportSpanProcessor(ConsoleSpanExporter())
)
@strawberry.type
class User:
name: str
@strawberry.type
class Query:
@strawberry.field
async def user(self, name: str) -> User:
await asyncio.sleep(0.1)
return User(name)
schema = strawberry.Schema(Query, extensions=[OpenTelemetryExtension])
This release disables tracing for default resolvers and introspection queries
This releases allows UNSET to be used anywhere and prevents mypy to report an error.
This releases adds support for strawberry.union inside mypy.
This release fixes an issue with the extension runner and async resolvers
Fixed bug where you couldn't use the same Union type multiple times in a schema.
Added strawberry.Private
type to mark fields as "private" so they don't show up in the GraphQL schema.
Example:
import strawberry
@strawberry.type
class User:
age: strawberry.Private[int]
@strawberry.field
def age_in_months(self) -> int:
return self.age * 12
Fix typo in type_resolver.py
This release fixes an issue with mypy when doing the following:
import strawberry
@strawberry.type
class User:
name: str = strawberry.field(description='Example')
This release adds support for Apollo Tracing and support for creating Strawberry extensions, here's how you can enable Apollo tracing:
from strawberry.extensions.tracing import ApolloTracingExtension
schema = strawberry.Schema(query=Query, extensions=[ApolloTracingExtension])
And here's an example of custom extension:
from strawberry.extensions import Extension
class MyExtension(Extension):
def get_results(self):
return {
"example": "this is an example for an extension"
}
schema = strawberry.Schema(query=Query, extensions=[MyExtension])
This release fixes an issue when trying to print a type with a UNSET default value
UnionDefinition
has been renamed toStrawberryUnion
strawberry.union
now returns an instance ofStrawberryUnion
instead of a dynamically generated class instance with a_union_definition
attribute of typeUnionDefinition
.
This release adds the py.typed
file for better mypy support.
This release fixes another issue with extending types.
This releases fixes an issue when extending types, now fields should work as they were working before even when extending an existing type.
Improves tooling by adding flake8-eradicate
to flake8
pre-commit
hook..
Previously, strawberry.field
had redundant arguments for the resolver, one for
when strawberry.field
was used as a decorator, and one for when it was used as
a function. These are now combined into a single argument.
The f
argument of strawberry.field
no longer exists. This is a
backwards-incompatible change, but should not affect many users. The f
argument was the first argument for strawberry.field
and its use was only
documented without the keyword. The fix is very straight-forward: replace any
f=
kwarg with resolver=
.
@strawberry.type
class Query:
my_int: int = strawberry.field(f=lambda: 5)
# becomes
my_int: int = strawberry.field(resolver=lambda: 5)
# no change
@strawberry.field
def my_float(self) -> float:
return 5.5
Other (minor) breaking changes
MissingArgumentsAnnotationsError
's message now uses the original Python field name instead of the GraphQL field name. The error can only be thrown while instantiating a strawberry.field, so the Python field name should be more helpful.- As a result,
strawberry.arguments.get_arguments_from_resolver()
now only takes one field -- theresolver
Callable. MissingFieldAnnotationError
is now thrown when a strawberry.field is not type-annotated but also has no resolver to determine its type
This release fixes the Flask view that was returning 400 when there were errors in the GraphQL results. Now it always returns 200.
Add process_result
to views for Django, Flask and ASGI. They can be overridden
to provide a custom response and also to process results and errors.
It also removes request
from Flask view's get_root_value
and get_context
since request in Flask is a global.
Django example:
# views.py
from django.http import HttpRequest
from strawberry.django.views import GraphQLView as BaseGraphQLView
from strawberry.http import GraphQLHTTPResponse
from strawberry.types import ExecutionResult
class GraphQLView(BaseGraphQLView):
def process_result(self, request: HttpRequest, result: ExecutionResult) -> GraphQLHTTPResponse:
return {"data": result.data, "errors": result.errors or []}
Flask example:
# views.py
from strawberry.flask.views import GraphQLView as BaseGraphQLView
from strawberry.http import GraphQLHTTPResponse
from strawberry.types import ExecutionResult
class GraphQLView(BaseGraphQLView):
def process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse:
return {"data": result.data, "errors": result.errors or []}
ASGI example:
from strawberry.asgi import GraphQL as BaseGraphQL
from strawberry.http import GraphQLHTTPResponse
from strawberry.types import ExecutionResult
from starlette.requests import Request
from .schema import schema
class GraphQL(BaseGraphQLView):
async def process_result(self, request: Request, result: ExecutionResult) -> GraphQLHTTPResponse:
return {"data": result.data, "errors": result.errors or []}
This releases fixes the check for unset values.
Add functions get_root_value
and get_context
to views for Django, Flask and
ASGI. They can be overridden to provide custom values per request.
Django example:
# views.py
from strawberry.django.views import GraphQLView as BaseGraphQLView
class GraphQLView(BaseGraphQLView):
def get_context(self, request):
return {
"request": request,
"custom_context_value": "Hi!",
}
def get_root_value(self, request):
return {
"custom_root_value": "π",
}
# urls.py
from django.urls import path
from .views import GraphQLView
from .schema import schema
urlpatterns = [
path("graphql/", GraphQLView.as_view(schema=schema)),
]
Flask example:
# views.py
from strawberry.flask.views import GraphQLView as BaseGraphQLView
class GraphQLView(BaseGraphQLView):
def get_context(self, request):
return {
"request": request,
"custom_context_value": "Hi!",
}
def get_root_value(self, request):
return {
"custom_root_value": "π",
}
# app.py
from flask import Flask
from .views import GraphQLView
from .schema import schema
app = Flask(__name__)
app.add_url_rule(
"/graphql",
view_func=GraphQLView.as_view("graphql_view", schema=schema),
)
ASGI example:
# app.py
from strawberry.asgi import GraphQL as BaseGraphQL
from .schema import schema
class GraphQL(BaseGraphQLView):
async def get_context(self, request):
return {
"request": request,
"custom_context_value": "Hi!",
}
async def get_root_value(self, request):
return {
"custom_root_value": "π",
}
app = GraphQL(schema)
Support for default_value
on inputs.
Usage:
class MyInput:
s: Optional[str] = None
i: int = 0
input MyInput {
s: String = null
i: Int! = 0
}
This release adds support for file uploads within Django.
We follow the following spec: https://github.com/jaydenseric/graphql-multipart-request-spec
Example:
import strawberry
from strawberry.file_uploads import Upload
@strawberry.type
class Mutation:
@strawberry.mutation
def read_text(self, text_file: Upload) -> str:
return text_file.read().decode()
Fix issue when reusing an interface
Fix issue when using generic types with federation
Add support for using lazy types inside generics.
This releae add support for UUID as field types. They will be represented as GraphQL ID in the GraphQL schema.
This release fixes support for PEP-563, now you can safely use from __future__ import annotations
,
like the following example:
from __future__ import annotations
@strawberry.type
class Query:
me: MyType = strawberry.field(name="myself")
@strawberry.type
class MyType:
id: strawberry.ID
This releases brings a much needed internal refactor of how we generate GraphQL types from class definitions. Hopefully this will make easier to extend Strawberry in future.
There are some internal breaking changes, so if you encounter any issue let us know and well try to help with the migration.
In addition to the internal refactor we also fixed some bugs and improved
the public api for the schema class. Now you can run queries directly
on the schema by running schema.execute
, schema.execute_sync
and
schema.subscribe
on your schema.
Add websocket object to the subscription context.
This PR fixes a bug when declaring multiple non-named union types
Optimized signature reflection and added benchmarks.
This release fixes an issue when using named union types in generic types, for example using an optional union. This is now properly supported:
@strawberry.type
class A:
a: int
@strawberry.type
class B:
b: int
Result = strawberry.union("Result", (A, B))
@strawberry.type
class Query:
ab: Optional[Result] = None
Fix typo in Decimal description
This release adds support for decimal type, example:
@strawberry.type
class Query:
@strawberry.field
def example_decimal(self) -> Decimal:
return Decimal("3.14159")
This release disables subscription in GraphiQL where it is not supported.
Fixes a bug when using unions and lists together
Argument conversion doesn't populate missing args with defaults.
@strawberry.field
def hello(self, null_or_unset: Optional[str] = UNSET, nullable: str = None) -> None:
pass
This releases adds experimental support for apollo federation.
Here's an example:
import strawberry
@strawberry.federation.type(extend=True, keys=["id"])
class Campaign:
id: strawberry.ID = strawberry.federation.field(external=True)
@strawberry.field
def title(self) -> str:
return f"Title for {self.id}"
@classmethod
def resolve_reference(cls, id):
return Campaign(id)
@strawberry.federation.type(extend=True)
class Query:
@strawberry.field
def strawberry(self) -> str:
return "π"
schema = strawberry.federation.Schema(query=Query, types=[Campaign])
Default values make input arguments nullable when the default is None.
class Query:
@strawberry.field
def hello(self, i: int = 0, s: str = None) -> str:
return s
type Query {
hello(i: Int! = 0, s: String): String!
}
Added sentinel value for input parameters that aren't sent by the clients. It checks for when a field is unset.
Support for default_value
on inputs and arguments.
Usage:
class MyInput:
s: Optional[str]
i: int = 0
input MyInput {
s: String
i: Int! = 0
}
Improves tooling by updating pre-commit
hooks and adding pre-commit
to
pyproject.toml
.
Add support for setting root_value
in asgi.
Usage:
schema = strawberry.Schema(query=Query)
app = strawberry.asgi.GraphQL(schema, root_value=Query())
Fix error when a subscription accepted input arguments
This release add supports for named unions, now you can create a new union type by writing:
Result = strawberry.union("Result", (A, B), description="Example Result")
This also improves the support for Union and Generic types, as it was broken before.
This release fixes a bug introduced by 0.24.0
This releases allows to use resolver without having to specify root and info arguments:
def function_resolver() -> str:
return "I'm a function resolver"
def function_resolver_with_params(x: str) -> str:
return f"I'm {x}"
@strawberry.type
class Query:
hello: str = strawberry.field(resolver=function_resolver)
hello_with_params: str = strawberry.field(
resolver=function_resolver_with_params
)
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "I'm a function resolver"
@strawberry.field
def hello_with_params(self, x: str) -> str:
return f"I'm {x}"
This makes it easier to reuse existing functions and makes code cleaner when not using info or root.
This release fixes the dependency of GraphQL-core
This releases updates the debug server to serve the API on '/' as well as '/graphql'.
Removes the need for duplicate graphiql template file.
This releases replaces the playground with GraphiQL including the GraphiQL explorer plugin.
This release adds support for generic types, allowing to reuse types, here's an example:
T = typing.TypeVar("T")
@strawberry.type
class Edge(typing.Generic[T]):
cursor: strawberry.ID
node: T
@strawberry.type
class Query:
@strawberry.field
def int_edge(self, info, **kwargs) -> Edge[int]:
return Edge(cursor=strawberry.ID("1"), node=1)
Update version of graphql-core to 3.1.0b2
Added a Flask view that allows you to query the schema and interact with it via GraphiQL.
Usage:
# app.py
from strawberry.flask.views import GraphQLView
from your_project.schema import schema
app = Flask(__name__)
app.add_url_rule(
"/graphql", view_func=GraphQLView.as_view("graphql_view", schema=schema)
)
if __name__ == "__main__":
app.run(debug=True)
Improve datetime, date and time types conversion. Removes aniso dependency and also adds support for python types, so now we can do use python datetime's types instead of our custom scalar types.
This version adds support for Django 3.0
Fix directives bugs:
-
Fix autogenerated
return
argument bug -
Fix include and skip failure bug
This release improves support for permissions (it is a breaking change).
Now you will receive the source and the arguments in the has_permission
method,
so you can run more complex permission checks. It also allows to use permissions
on fields, here's an example:
import strawberry
from strawberry.permission import BasePermission
class IsAdmin(BasePermission):
message = "You are not authorized"
def has_permission(self, source, info):
return source.name.lower() == "Patrick" or _is_admin(info)
@strawberry.type
class User:
name: str
email: str = strawberry.field(permission_classes=[IsAdmin])
@strawberry.type
class Query:
@strawberry.field(permission_classes=[IsAdmin])
def user(self, info) -> str:
return User(name="Patrick", email="[email protected]")
This releases removes support for async resolver in django as they causes issues when accessing the databases.
This release improves support for django and asgi integration.
It allows to use async resolvers when using django. It also changes the status code from 400 to 200 even if there are errors this makes it possible to still use other fields even if one raised an error.
We also moved strawberry.contrib.django to strawberry.django, so if you're using the django view make sure you update the paths.
Fix missing support for booleans when converting arguments
This releases fixes an issue when converting complex input types, now it should support lists of complex types properly.
Set is_type_of
only when the type implements an interface,
this allows to return different (but compatible) types in basic cases.
Refactored CLI folder structure, importing click commands from a subfolder. Follows click's complex example.
Add support for custom GraphQL scalars.
Tests are now run on GitHub actions on both python 3.7 and python3.8 π
Fixed some typos in contributing.md .
Fixed some typos in readme.md and contributing.md.
Minimal support for registering types without fields and abstract interface querying.
Grammar fixes - changed 'corresponding tests, if tests' to 'corresponding tests. If tests' and removed extraneous period from 'Provide specific examples to demonstrate the steps..'. Also made 'Enhancement' lowercase to stay consistent with its usage in documentation and changed 'on the Strawberry' to 'to Strawberry'.
Added issue template files (bug_report.md, feature_request.md, other_issues.md) and a pull request template file.
Fix execution of async resolvers.
Typo fix - changed the spelling from 'follwing' to 'following'.
Updated docs to provide reference on how to use Django view.
Removed custom representation for Strawberry types, this should make using types much nicer.
Switched from graphql-core-next
dependency to graphql-core@^3.0.0a0
.
Fixes MYPY plugin
Add the flake8-bugbear linting plugin to catch likely bugs
Fixed conversion of enum when value was falsy.
Fixed issue when trying to convert optional arguments to a type
Fix issue with converting arguments with optional fields.
Thanks to @sciyoshi for the fix!
Added a Django view that allows you to query the schema and interact with it via GraphiQL
Usage:
# Install
$ pip install 'strawberry-graphql[django]'
# settings.py
INSTALLED_APPS = [
...
'strawberry.django',
]
# urls.py
from strawberry.django.views import GraphQLView
from your_project.schema import schema
urlpatterns = [
path('graphql/', GraphQLView.as_view(schema=schema)),
]
This release doesn't add any feature or fixes, but it fixes an issue with checking for release files when submitting PRs β¨.
Fixes the conversion of Enums in resolvers, arguments and input types.
Add a mypy plugin that enables typechecking Strawberry types
Fix List types being converted to Optional GraphQL lists.
This release doesn't add any feature or fixes, it only introduces a GitHub Action to let people know how to add a RELEASE.md file when submitting a PR.
Added support for defining query directives, example:
import strawberry
from strawberry.directive import DirectiveLocation
@strawberry.type
class Query:
cake: str = "made_in_switzerland"
@strawberry.directive(
locations=[DirectiveLocation.FIELD], description="Make string uppercase"
)
def uppercase(value: str, example: str):
return value.upper()
schema = strawberry.Schema(query=Query, directives=[uppercase])
Improve dict_to_type conversion by checking if the field has a different name or case
Fix field initialization not allowed when using strawberry.field
in an input
type
@strawberry.input
class Say:
what = strawberry.field(is_input=True)
Allow the usage of Union types in the mutations
@strawberry.type
class A:
x: int
@strawberry.type
class B:
y: int
@strawberry.type
class Mutation:
@strawberry.mutation
def hello(self, info) -> Union[A, B]:
return B(y=5)
schema = strawberry.Schema(query=A, mutation=Mutation)
query = """
mutation {
hello {
__typename
... on A {
x
}
... on B {
y
}
}
}
"""
Fix missing fields when extending a class, now we can do this:
@strawberry.type
class Parent:
cheese: str = "swiss"
@strawberry.field
def friend(self, info) -> str:
return 'food'
@strawberry.type
class Schema(Parent):
cake: str = "made_in_swiss"
This release adds field support for permissions
import strawberry
from strawberry.permission import BasePermission
class IsAdmin(BasePermission):
message = "You are not authorized"
def has_permission(self, info):
return False
@strawberry.type
class Query:
@strawberry.field(permission_classes=[IsAdmin])
def hello(self, info) -> str:
return "Hello"
This releases adds support for ASGI 3.0
from strawberry.asgi import GraphQL
from starlette.applications import Starlette
graphql_app = GraphQL(schema_module.schema, debug=True)
app = Starlette(debug=True)
app.add_route("/graphql", graphql_app)
app.add_websocket_route("/graphql", graphql_app)
Added support for optional fields with default arguments in the GraphQL schema when default arguments are passed to the resolver.
Example:
@strawberry.type
class Query:
@strawberry.field
def hello(self, info, name: str = "world") -> str:
return name
type Query {
hello(name: String = "world"): String
}
Fixed issue that was prevent usage of InitVars. Now you can safely use InitVar to prevent fields from showing up in the schema:
@strawberry.type
class Category:
name: str
id: InitVar[str]
@strawberry.type
class Query:
@strawberry.field
def category(self, info) -> Category:
return Category(name="example", id="123")
Fixed logo on PyPI
Added support for passing resolver functions
def resolver(root, info, par: str) -> str:
return f"hello {par}"
@strawberry.type
class Query:
example: str = strawberry.field(resolver=resolver)
Also we updated some of the dependencies of the project
Added support for renaming fields. Example usage:
@strawberry.type
class Query:
example: str = strawberry.field(name='test')
Added support for declaring interface by using @strawberry.interface
Example:
@strawberry.interface
class Node:
id: strawberry.ID
This changes field to be lazy by default, allowing to use circular dependencies when declaring types.
Improve listing on pypi.org