We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Validate schema early
Currently graphql-core doesn't validate the schema until execution time (to allow for partial schema generation). Since strawberry doesn't support partial generation at the moment it would make sense to validate the schema as soon as it's instantiated so that any issues are raised early.

~~As a bonus it would be nice to be able to specify which validators to run.~~ Actually the schema validation is separate to the validate "rules" that I was thinking about here so this is not the right place to tackle that problem.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `strawberry/schema/schema.py`
Content:
```
1 from typing import Any, Dict, List, Optional, Sequence, Type, Union
2 
3 from graphql import GraphQLSchema, get_introspection_query, parse
4 from graphql.subscription import subscribe
5 from graphql.type.directives import specified_directives
6 
7 from strawberry.custom_scalar import ScalarDefinition
8 from strawberry.enum import EnumDefinition
9 from strawberry.extensions import Extension
10 from strawberry.types.types import TypeDefinition
11 from strawberry.union import StrawberryUnion
12 
13 from ..middleware import DirectivesMiddleware, Middleware
14 from ..printer import print_schema
15 from .base import ExecutionResult
16 from .execute import execute, execute_sync
17 from .types import ConcreteType, get_directive_type, get_object_type
18 
19 
20 class Schema:
21     def __init__(
22         self,
23         # TODO: can we make sure we only allow to pass something that has been decorated?
24         query: Type,
25         mutation: Optional[Type] = None,
26         subscription: Optional[Type] = None,
27         directives=(),
28         types=(),
29         extensions: Sequence[Type[Extension]] = (),
30     ):
31         self.extensions = extensions
32         self.type_map: Dict[str, ConcreteType] = {}
33 
34         query_type = get_object_type(query, self.type_map)
35         mutation_type = get_object_type(mutation, self.type_map) if mutation else None
36         subscription_type = (
37             get_object_type(subscription, self.type_map) if subscription else None
38         )
39 
40         self.middleware: List[Middleware] = [DirectivesMiddleware(directives)]
41 
42         directives = [
43             get_directive_type(directive, self.type_map) for directive in directives
44         ]
45 
46         self._schema = GraphQLSchema(
47             query=query_type,
48             mutation=mutation_type,
49             subscription=subscription_type if subscription else None,
50             directives=specified_directives + directives,
51             types=[get_object_type(type, self.type_map) for type in types],
52         )
53 
54         self.query = self.type_map[query_type.name]
55 
56     def get_type_by_name(
57         self, name: str
58     ) -> Optional[
59         Union[TypeDefinition, ScalarDefinition, EnumDefinition, StrawberryUnion]
60     ]:
61         if name in self.type_map:
62             return self.type_map[name].definition
63 
64         return None
65 
66     async def execute(
67         self,
68         query: str,
69         variable_values: Optional[Dict[str, Any]] = None,
70         context_value: Optional[Any] = None,
71         root_value: Optional[Any] = None,
72         operation_name: Optional[str] = None,
73     ) -> ExecutionResult:
74         result = await execute(
75             self._schema,
76             query,
77             variable_values=variable_values,
78             root_value=root_value,
79             context_value=context_value,
80             operation_name=operation_name,
81             additional_middlewares=self.middleware,
82             extensions=self.extensions,
83         )
84 
85         return ExecutionResult(
86             data=result.data,
87             errors=result.errors,
88             extensions=result.extensions,
89         )
90 
91     def execute_sync(
92         self,
93         query: str,
94         variable_values: Optional[Dict[str, Any]] = None,
95         context_value: Optional[Any] = None,
96         root_value: Optional[Any] = None,
97         operation_name: Optional[str] = None,
98     ) -> ExecutionResult:
99         result = execute_sync(
100             self._schema,
101             query,
102             variable_values=variable_values,
103             root_value=root_value,
104             context_value=context_value,
105             operation_name=operation_name,
106             additional_middlewares=self.middleware,
107             extensions=self.extensions,
108         )
109 
110         return ExecutionResult(
111             data=result.data,
112             errors=result.errors,
113             extensions=result.extensions,
114         )
115 
116     async def subscribe(
117         self,
118         query: str,
119         variable_values: Optional[Dict[str, Any]] = None,
120         context_value: Optional[Any] = None,
121         root_value: Optional[Any] = None,
122         operation_name: Optional[str] = None,
123     ):
124         return await subscribe(
125             self._schema,
126             parse(query),
127             root_value=root_value,
128             context_value=context_value,
129             variable_values=variable_values,
130             operation_name=operation_name,
131         )
132 
133     def as_str(self) -> str:
134         return print_schema(self)
135 
136     __str__ = as_str
137 
138     def introspect(self) -> Dict[str, Any]:
139         """Return the introspection query result for the current schema
140 
141         Raises:
142             ValueError: If the introspection query fails due to an invalid schema
143         """
144         introspection = self.execute_sync(get_introspection_query())
145         if introspection.errors or not introspection.data:
146             raise ValueError(f"Invalid Schema. Errors {introspection.errors!r}")
147 
148         return introspection.data
149
```

Path: `strawberry/schema/execute.py`
Content:
```
1 from asyncio import ensure_future
2 from inspect import isawaitable
3 from typing import Any, Awaitable, Dict, List, Sequence, Type, cast
4 
5 from graphql import (
6     ExecutionResult as GraphQLExecutionResult,
7     GraphQLError,
8     GraphQLSchema,
9     execute as original_execute,
10     parse,
11 )
12 from graphql.type import validate_schema
13 from graphql.validation import validate
14 
15 from strawberry.extensions import Extension
16 from strawberry.extensions.runner import ExtensionsRunner
17 from strawberry.types import ExecutionContext, ExecutionResult
18 
19 
20 async def execute(
21     schema: GraphQLSchema,
22     query: str,
23     extensions: Sequence[Type[Extension]],
24     root_value: Any = None,
25     context_value: Any = None,
26     variable_values: Dict[str, Any] = None,
27     additional_middlewares: List[Any] = None,
28     operation_name: str = None,
29 ) -> ExecutionResult:
30     execution_context = ExecutionContext(
31         query=query,
32         context=context_value,
33         variables=variable_values,
34         operation_name=operation_name,
35     )
36 
37     extensions_runner = ExtensionsRunner(
38         execution_context=execution_context,
39         extensions=[extension() for extension in extensions],
40     )
41 
42     additional_middlewares = additional_middlewares or []
43 
44     with extensions_runner.request():
45         schema_validation_errors = validate_schema(schema)
46 
47         if schema_validation_errors:
48             return ExecutionResult(
49                 data=None,
50                 errors=schema_validation_errors,
51                 extensions=extensions_runner.get_extensions_results(),
52             )
53 
54         try:
55             with extensions_runner.parsing():
56                 document = parse(query)
57         except GraphQLError as error:
58             return ExecutionResult(
59                 data=None,
60                 errors=[error],
61                 extensions=extensions_runner.get_extensions_results(),
62             )
63 
64         except Exception as error:  # pragma: no cover
65             error = GraphQLError(str(error), original_error=error)
66 
67             return ExecutionResult(
68                 data=None,
69                 errors=[error],
70                 extensions=extensions_runner.get_extensions_results(),
71             )
72 
73         with extensions_runner.validation():
74             validation_errors = validate(schema, document)
75 
76         if validation_errors:
77             return ExecutionResult(data=None, errors=validation_errors)
78 
79         result = original_execute(
80             schema,
81             document,
82             root_value=root_value,
83             middleware=extensions_runner.as_middleware_manager(*additional_middlewares),
84             variable_values=variable_values,
85             operation_name=operation_name,
86             context_value=context_value,
87         )
88 
89         if isawaitable(result):
90             result = await cast(Awaitable[GraphQLExecutionResult], result)
91 
92     result = cast(GraphQLExecutionResult, result)
93 
94     return ExecutionResult(
95         data=result.data,
96         errors=result.errors,
97         extensions=extensions_runner.get_extensions_results(),
98     )
99 
100 
101 def execute_sync(
102     schema: GraphQLSchema,
103     query: str,
104     extensions: Sequence[Type[Extension]],
105     root_value: Any = None,
106     context_value: Any = None,
107     variable_values: Dict[str, Any] = None,
108     additional_middlewares: List[Any] = None,
109     operation_name: str = None,
110 ) -> ExecutionResult:
111     execution_context = ExecutionContext(
112         query=query,
113         context=context_value,
114         variables=variable_values,
115         operation_name=operation_name,
116     )
117     extensions_runner = ExtensionsRunner(
118         execution_context=execution_context,
119         extensions=[extension() for extension in extensions],
120     )
121 
122     additional_middlewares = additional_middlewares or []
123 
124     with extensions_runner.request():
125         schema_validation_errors = validate_schema(schema)
126 
127         if schema_validation_errors:
128             return ExecutionResult(
129                 data=None,
130                 errors=schema_validation_errors,
131                 extensions=extensions_runner.get_extensions_results(),
132             )
133 
134         try:
135             with extensions_runner.parsing():
136                 document = parse(query)
137         except GraphQLError as error:
138             return ExecutionResult(
139                 data=None,
140                 errors=[error],
141                 extensions=extensions_runner.get_extensions_results(),
142             )
143 
144         except Exception as error:  # pragma: no cover
145             error = GraphQLError(str(error), original_error=error)
146 
147             return ExecutionResult(
148                 data=None,
149                 errors=[error],
150                 extensions=extensions_runner.get_extensions_results(),
151             )
152 
153         with extensions_runner.validation():
154             validation_errors = validate(schema, document)
155 
156         if validation_errors:
157             return ExecutionResult(data=None, errors=validation_errors)
158 
159         result = original_execute(
160             schema,
161             document,
162             root_value=root_value,
163             middleware=extensions_runner.as_middleware_manager(*additional_middlewares),
164             variable_values=variable_values,
165             operation_name=operation_name,
166             context_value=context_value,
167         )
168 
169         if isawaitable(result):
170             ensure_future(cast(Awaitable[GraphQLExecutionResult], result)).cancel()
171             raise RuntimeError("GraphQL execution failed to complete synchronously.")
172 
173     result = cast(GraphQLExecutionResult, result)
174 
175     return ExecutionResult(
176         data=result.data,
177         errors=result.errors,
178         extensions=extensions_runner.get_extensions_results(),
179     )
180
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/strawberry/schema/execute.py b/strawberry/schema/execute.py
--- a/strawberry/schema/execute.py
+++ b/strawberry/schema/execute.py
@@ -9,7 +9,6 @@
     execute as original_execute,
     parse,
 )
-from graphql.type import validate_schema
 from graphql.validation import validate
 
 from strawberry.extensions import Extension
@@ -42,14 +41,8 @@
     additional_middlewares = additional_middlewares or []
 
     with extensions_runner.request():
-        schema_validation_errors = validate_schema(schema)
-
-        if schema_validation_errors:
-            return ExecutionResult(
-                data=None,
-                errors=schema_validation_errors,
-                extensions=extensions_runner.get_extensions_results(),
-            )
+        # Note: In graphql-core the schema would be validated here but in
+        # Strawberry we are validating it at initialisation time instead
 
         try:
             with extensions_runner.parsing():
@@ -122,14 +115,8 @@
     additional_middlewares = additional_middlewares or []
 
     with extensions_runner.request():
-        schema_validation_errors = validate_schema(schema)
-
-        if schema_validation_errors:
-            return ExecutionResult(
-                data=None,
-                errors=schema_validation_errors,
-                extensions=extensions_runner.get_extensions_results(),
-            )
+        # Note: In graphql-core the schema would be validated here but in
+        # Strawberry we are validating it at initialisation time instead
 
         try:
             with extensions_runner.parsing():
diff --git a/strawberry/schema/schema.py b/strawberry/schema/schema.py
--- a/strawberry/schema/schema.py
+++ b/strawberry/schema/schema.py
@@ -1,6 +1,6 @@
 from typing import Any, Dict, List, Optional, Sequence, Type, Union
 
-from graphql import GraphQLSchema, get_introspection_query, parse
+from graphql import GraphQLSchema, get_introspection_query, parse, validate_schema
 from graphql.subscription import subscribe
 from graphql.type.directives import specified_directives
 
@@ -51,6 +51,13 @@
             types=[get_object_type(type, self.type_map) for type in types],
         )
 
+        # Validate schema early because we want developers to know about
+        # possible issues as soon as possible
+        errors = validate_schema(self._schema)
+        if errors:
+            formatted_errors = "\n\n".join(f"❌ {error.message}" for error in errors)
+            raise ValueError(f"Invalid Schema. Errors:\n\n{formatted_errors}")
+
         self.query = self.type_map[query_type.name]
 
     def get_type_by_name(

{"golden_diff": "diff --git a/strawberry/schema/execute.py b/strawberry/schema/execute.py\n--- a/strawberry/schema/execute.py\n+++ b/strawberry/schema/execute.py\n@@ -9,7 +9,6 @@\n     execute as original_execute,\n     parse,\n )\n-from graphql.type import validate_schema\n from graphql.validation import validate\n \n from strawberry.extensions import Extension\n@@ -42,14 +41,8 @@\n     additional_middlewares = additional_middlewares or []\n \n     with extensions_runner.request():\n-        schema_validation_errors = validate_schema(schema)\n-\n-        if schema_validation_errors:\n-            return ExecutionResult(\n-                data=None,\n-                errors=schema_validation_errors,\n-                extensions=extensions_runner.get_extensions_results(),\n-            )\n+        # Note: In graphql-core the schema would be validated here but in\n+        # Strawberry we are validating it at initialisation time instead\n \n         try:\n             with extensions_runner.parsing():\n@@ -122,14 +115,8 @@\n     additional_middlewares = additional_middlewares or []\n \n     with extensions_runner.request():\n-        schema_validation_errors = validate_schema(schema)\n-\n-        if schema_validation_errors:\n-            return ExecutionResult(\n-                data=None,\n-                errors=schema_validation_errors,\n-                extensions=extensions_runner.get_extensions_results(),\n-            )\n+        # Note: In graphql-core the schema would be validated here but in\n+        # Strawberry we are validating it at initialisation time instead\n \n         try:\n             with extensions_runner.parsing():\ndiff --git a/strawberry/schema/schema.py b/strawberry/schema/schema.py\n--- a/strawberry/schema/schema.py\n+++ b/strawberry/schema/schema.py\n@@ -1,6 +1,6 @@\n from typing import Any, Dict, List, Optional, Sequence, Type, Union\n \n-from graphql import GraphQLSchema, get_introspection_query, parse\n+from graphql import GraphQLSchema, get_introspection_query, parse, validate_schema\n from graphql.subscription import subscribe\n from graphql.type.directives import specified_directives\n \n@@ -51,6 +51,13 @@\n             types=[get_object_type(type, self.type_map) for type in types],\n         )\n \n+        # Validate schema early because we want developers to know about\n+        # possible issues as soon as possible\n+        errors = validate_schema(self._schema)\n+        if errors:\n+            formatted_errors = \"\\n\\n\".join(f\"\u274c {error.message}\" for error in errors)\n+            raise ValueError(f\"Invalid Schema. Errors:\\n\\n{formatted_errors}\")\n+\n         self.query = self.type_map[query_type.name]\n \n     def get_type_by_name(\n", "issue": "Validate schema early\nCurrently graphql-core doesn't validate the schema until execution time (to allow for partial schema generation). Since strawberry doesn't support partial generation at the moment it would make sense to validate the schema as soon as it's instantiated so that any issues are raised early.\r\n\r\n~~As a bonus it would be nice to be able to specify which validators to run.~~ Actually the schema validation is separate to the validate \"rules\" that I was thinking about here so this is not the right place to tackle that problem.\n", "before_files": [{"content": "from typing import Any, Dict, List, Optional, Sequence, Type, Union\n\nfrom graphql import GraphQLSchema, get_introspection_query, parse\nfrom graphql.subscription import subscribe\nfrom graphql.type.directives import specified_directives\n\nfrom strawberry.custom_scalar import ScalarDefinition\nfrom strawberry.enum import EnumDefinition\nfrom strawberry.extensions import Extension\nfrom strawberry.types.types import TypeDefinition\nfrom strawberry.union import StrawberryUnion\n\nfrom ..middleware import DirectivesMiddleware, Middleware\nfrom ..printer import print_schema\nfrom .base import ExecutionResult\nfrom .execute import execute, execute_sync\nfrom .types import ConcreteType, get_directive_type, get_object_type\n\n\nclass Schema:\n    def __init__(\n        self,\n        # TODO: can we make sure we only allow to pass something that has been decorated?\n        query: Type,\n        mutation: Optional[Type] = None,\n        subscription: Optional[Type] = None,\n        directives=(),\n        types=(),\n        extensions: Sequence[Type[Extension]] = (),\n    ):\n        self.extensions = extensions\n        self.type_map: Dict[str, ConcreteType] = {}\n\n        query_type = get_object_type(query, self.type_map)\n        mutation_type = get_object_type(mutation, self.type_map) if mutation else None\n        subscription_type = (\n            get_object_type(subscription, self.type_map) if subscription else None\n        )\n\n        self.middleware: List[Middleware] = [DirectivesMiddleware(directives)]\n\n        directives = [\n            get_directive_type(directive, self.type_map) for directive in directives\n        ]\n\n        self._schema = GraphQLSchema(\n            query=query_type,\n            mutation=mutation_type,\n            subscription=subscription_type if subscription else None,\n            directives=specified_directives + directives,\n            types=[get_object_type(type, self.type_map) for type in types],\n        )\n\n        self.query = self.type_map[query_type.name]\n\n    def get_type_by_name(\n        self, name: str\n    ) -> Optional[\n        Union[TypeDefinition, ScalarDefinition, EnumDefinition, StrawberryUnion]\n    ]:\n        if name in self.type_map:\n            return self.type_map[name].definition\n\n        return None\n\n    async def execute(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ) -> ExecutionResult:\n        result = await execute(\n            self._schema,\n            query,\n            variable_values=variable_values,\n            root_value=root_value,\n            context_value=context_value,\n            operation_name=operation_name,\n            additional_middlewares=self.middleware,\n            extensions=self.extensions,\n        )\n\n        return ExecutionResult(\n            data=result.data,\n            errors=result.errors,\n            extensions=result.extensions,\n        )\n\n    def execute_sync(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ) -> ExecutionResult:\n        result = execute_sync(\n            self._schema,\n            query,\n            variable_values=variable_values,\n            root_value=root_value,\n            context_value=context_value,\n            operation_name=operation_name,\n            additional_middlewares=self.middleware,\n            extensions=self.extensions,\n        )\n\n        return ExecutionResult(\n            data=result.data,\n            errors=result.errors,\n            extensions=result.extensions,\n        )\n\n    async def subscribe(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ):\n        return await subscribe(\n            self._schema,\n            parse(query),\n            root_value=root_value,\n            context_value=context_value,\n            variable_values=variable_values,\n            operation_name=operation_name,\n        )\n\n    def as_str(self) -> str:\n        return print_schema(self)\n\n    __str__ = as_str\n\n    def introspect(self) -> Dict[str, Any]:\n        \"\"\"Return the introspection query result for the current schema\n\n        Raises:\n            ValueError: If the introspection query fails due to an invalid schema\n        \"\"\"\n        introspection = self.execute_sync(get_introspection_query())\n        if introspection.errors or not introspection.data:\n            raise ValueError(f\"Invalid Schema. Errors {introspection.errors!r}\")\n\n        return introspection.data\n", "path": "strawberry/schema/schema.py"}, {"content": "from asyncio import ensure_future\nfrom inspect import isawaitable\nfrom typing import Any, Awaitable, Dict, List, Sequence, Type, cast\n\nfrom graphql import (\n    ExecutionResult as GraphQLExecutionResult,\n    GraphQLError,\n    GraphQLSchema,\n    execute as original_execute,\n    parse,\n)\nfrom graphql.type import validate_schema\nfrom graphql.validation import validate\n\nfrom strawberry.extensions import Extension\nfrom strawberry.extensions.runner import ExtensionsRunner\nfrom strawberry.types import ExecutionContext, ExecutionResult\n\n\nasync def execute(\n    schema: GraphQLSchema,\n    query: str,\n    extensions: Sequence[Type[Extension]],\n    root_value: Any = None,\n    context_value: Any = None,\n    variable_values: Dict[str, Any] = None,\n    additional_middlewares: List[Any] = None,\n    operation_name: str = None,\n) -> ExecutionResult:\n    execution_context = ExecutionContext(\n        query=query,\n        context=context_value,\n        variables=variable_values,\n        operation_name=operation_name,\n    )\n\n    extensions_runner = ExtensionsRunner(\n        execution_context=execution_context,\n        extensions=[extension() for extension in extensions],\n    )\n\n    additional_middlewares = additional_middlewares or []\n\n    with extensions_runner.request():\n        schema_validation_errors = validate_schema(schema)\n\n        if schema_validation_errors:\n            return ExecutionResult(\n                data=None,\n                errors=schema_validation_errors,\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        try:\n            with extensions_runner.parsing():\n                document = parse(query)\n        except GraphQLError as error:\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        except Exception as error:  # pragma: no cover\n            error = GraphQLError(str(error), original_error=error)\n\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        with extensions_runner.validation():\n            validation_errors = validate(schema, document)\n\n        if validation_errors:\n            return ExecutionResult(data=None, errors=validation_errors)\n\n        result = original_execute(\n            schema,\n            document,\n            root_value=root_value,\n            middleware=extensions_runner.as_middleware_manager(*additional_middlewares),\n            variable_values=variable_values,\n            operation_name=operation_name,\n            context_value=context_value,\n        )\n\n        if isawaitable(result):\n            result = await cast(Awaitable[GraphQLExecutionResult], result)\n\n    result = cast(GraphQLExecutionResult, result)\n\n    return ExecutionResult(\n        data=result.data,\n        errors=result.errors,\n        extensions=extensions_runner.get_extensions_results(),\n    )\n\n\ndef execute_sync(\n    schema: GraphQLSchema,\n    query: str,\n    extensions: Sequence[Type[Extension]],\n    root_value: Any = None,\n    context_value: Any = None,\n    variable_values: Dict[str, Any] = None,\n    additional_middlewares: List[Any] = None,\n    operation_name: str = None,\n) -> ExecutionResult:\n    execution_context = ExecutionContext(\n        query=query,\n        context=context_value,\n        variables=variable_values,\n        operation_name=operation_name,\n    )\n    extensions_runner = ExtensionsRunner(\n        execution_context=execution_context,\n        extensions=[extension() for extension in extensions],\n    )\n\n    additional_middlewares = additional_middlewares or []\n\n    with extensions_runner.request():\n        schema_validation_errors = validate_schema(schema)\n\n        if schema_validation_errors:\n            return ExecutionResult(\n                data=None,\n                errors=schema_validation_errors,\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        try:\n            with extensions_runner.parsing():\n                document = parse(query)\n        except GraphQLError as error:\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        except Exception as error:  # pragma: no cover\n            error = GraphQLError(str(error), original_error=error)\n\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        with extensions_runner.validation():\n            validation_errors = validate(schema, document)\n\n        if validation_errors:\n            return ExecutionResult(data=None, errors=validation_errors)\n\n        result = original_execute(\n            schema,\n            document,\n            root_value=root_value,\n            middleware=extensions_runner.as_middleware_manager(*additional_middlewares),\n            variable_values=variable_values,\n            operation_name=operation_name,\n            context_value=context_value,\n        )\n\n        if isawaitable(result):\n            ensure_future(cast(Awaitable[GraphQLExecutionResult], result)).cancel()\n            raise RuntimeError(\"GraphQL execution failed to complete synchronously.\")\n\n    result = cast(GraphQLExecutionResult, result)\n\n    return ExecutionResult(\n        data=result.data,\n        errors=result.errors,\n        extensions=extensions_runner.get_extensions_results(),\n    )\n", "path": "strawberry/schema/execute.py"}], "after_files": [{"content": "from typing import Any, Dict, List, Optional, Sequence, Type, Union\n\nfrom graphql import GraphQLSchema, get_introspection_query, parse, validate_schema\nfrom graphql.subscription import subscribe\nfrom graphql.type.directives import specified_directives\n\nfrom strawberry.custom_scalar import ScalarDefinition\nfrom strawberry.enum import EnumDefinition\nfrom strawberry.extensions import Extension\nfrom strawberry.types.types import TypeDefinition\nfrom strawberry.union import StrawberryUnion\n\nfrom ..middleware import DirectivesMiddleware, Middleware\nfrom ..printer import print_schema\nfrom .base import ExecutionResult\nfrom .execute import execute, execute_sync\nfrom .types import ConcreteType, get_directive_type, get_object_type\n\n\nclass Schema:\n    def __init__(\n        self,\n        # TODO: can we make sure we only allow to pass something that has been decorated?\n        query: Type,\n        mutation: Optional[Type] = None,\n        subscription: Optional[Type] = None,\n        directives=(),\n        types=(),\n        extensions: Sequence[Type[Extension]] = (),\n    ):\n        self.extensions = extensions\n        self.type_map: Dict[str, ConcreteType] = {}\n\n        query_type = get_object_type(query, self.type_map)\n        mutation_type = get_object_type(mutation, self.type_map) if mutation else None\n        subscription_type = (\n            get_object_type(subscription, self.type_map) if subscription else None\n        )\n\n        self.middleware: List[Middleware] = [DirectivesMiddleware(directives)]\n\n        directives = [\n            get_directive_type(directive, self.type_map) for directive in directives\n        ]\n\n        self._schema = GraphQLSchema(\n            query=query_type,\n            mutation=mutation_type,\n            subscription=subscription_type if subscription else None,\n            directives=specified_directives + directives,\n            types=[get_object_type(type, self.type_map) for type in types],\n        )\n\n        # Validate schema early because we want developers to know about\n        # possible issues as soon as possible\n        errors = validate_schema(self._schema)\n        if errors:\n            formatted_errors = \"\\n\\n\".join(f\"\u274c {error.message}\" for error in errors)\n            raise ValueError(f\"Invalid Schema. Errors:\\n\\n{formatted_errors}\")\n\n        self.query = self.type_map[query_type.name]\n\n    def get_type_by_name(\n        self, name: str\n    ) -> Optional[\n        Union[TypeDefinition, ScalarDefinition, EnumDefinition, StrawberryUnion]\n    ]:\n        if name in self.type_map:\n            return self.type_map[name].definition\n\n        return None\n\n    async def execute(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ) -> ExecutionResult:\n        result = await execute(\n            self._schema,\n            query,\n            variable_values=variable_values,\n            root_value=root_value,\n            context_value=context_value,\n            operation_name=operation_name,\n            additional_middlewares=self.middleware,\n            extensions=self.extensions,\n        )\n\n        return ExecutionResult(\n            data=result.data,\n            errors=result.errors,\n            extensions=result.extensions,\n        )\n\n    def execute_sync(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ) -> ExecutionResult:\n        result = execute_sync(\n            self._schema,\n            query,\n            variable_values=variable_values,\n            root_value=root_value,\n            context_value=context_value,\n            operation_name=operation_name,\n            additional_middlewares=self.middleware,\n            extensions=self.extensions,\n        )\n\n        return ExecutionResult(\n            data=result.data,\n            errors=result.errors,\n            extensions=result.extensions,\n        )\n\n    async def subscribe(\n        self,\n        query: str,\n        variable_values: Optional[Dict[str, Any]] = None,\n        context_value: Optional[Any] = None,\n        root_value: Optional[Any] = None,\n        operation_name: Optional[str] = None,\n    ):\n        return await subscribe(\n            self._schema,\n            parse(query),\n            root_value=root_value,\n            context_value=context_value,\n            variable_values=variable_values,\n            operation_name=operation_name,\n        )\n\n    def as_str(self) -> str:\n        return print_schema(self)\n\n    __str__ = as_str\n\n    def introspect(self) -> Dict[str, Any]:\n        \"\"\"Return the introspection query result for the current schema\n\n        Raises:\n            ValueError: If the introspection query fails due to an invalid schema\n        \"\"\"\n        introspection = self.execute_sync(get_introspection_query())\n        if introspection.errors or not introspection.data:\n            raise ValueError(f\"Invalid Schema. Errors {introspection.errors!r}\")\n\n        return introspection.data\n", "path": "strawberry/schema/schema.py"}, {"content": "from asyncio import ensure_future\nfrom inspect import isawaitable\nfrom typing import Any, Awaitable, Dict, List, Sequence, Type, cast\n\nfrom graphql import (\n    ExecutionResult as GraphQLExecutionResult,\n    GraphQLError,\n    GraphQLSchema,\n    execute as original_execute,\n    parse,\n)\nfrom graphql.validation import validate\n\nfrom strawberry.extensions import Extension\nfrom strawberry.extensions.runner import ExtensionsRunner\nfrom strawberry.types import ExecutionContext, ExecutionResult\n\n\nasync def execute(\n    schema: GraphQLSchema,\n    query: str,\n    extensions: Sequence[Type[Extension]],\n    root_value: Any = None,\n    context_value: Any = None,\n    variable_values: Dict[str, Any] = None,\n    additional_middlewares: List[Any] = None,\n    operation_name: str = None,\n) -> ExecutionResult:\n    execution_context = ExecutionContext(\n        query=query,\n        context=context_value,\n        variables=variable_values,\n        operation_name=operation_name,\n    )\n\n    extensions_runner = ExtensionsRunner(\n        execution_context=execution_context,\n        extensions=[extension() for extension in extensions],\n    )\n\n    additional_middlewares = additional_middlewares or []\n\n    with extensions_runner.request():\n        # Note: In graphql-core the schema would be validated here but in\n        # Strawberry we are validating it at initialisation time instead\n\n        try:\n            with extensions_runner.parsing():\n                document = parse(query)\n        except GraphQLError as error:\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        except Exception as error:  # pragma: no cover\n            error = GraphQLError(str(error), original_error=error)\n\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        with extensions_runner.validation():\n            validation_errors = validate(schema, document)\n\n        if validation_errors:\n            return ExecutionResult(data=None, errors=validation_errors)\n\n        result = original_execute(\n            schema,\n            document,\n            root_value=root_value,\n            middleware=extensions_runner.as_middleware_manager(*additional_middlewares),\n            variable_values=variable_values,\n            operation_name=operation_name,\n            context_value=context_value,\n        )\n\n        if isawaitable(result):\n            result = await cast(Awaitable[GraphQLExecutionResult], result)\n\n    result = cast(GraphQLExecutionResult, result)\n\n    return ExecutionResult(\n        data=result.data,\n        errors=result.errors,\n        extensions=extensions_runner.get_extensions_results(),\n    )\n\n\ndef execute_sync(\n    schema: GraphQLSchema,\n    query: str,\n    extensions: Sequence[Type[Extension]],\n    root_value: Any = None,\n    context_value: Any = None,\n    variable_values: Dict[str, Any] = None,\n    additional_middlewares: List[Any] = None,\n    operation_name: str = None,\n) -> ExecutionResult:\n    execution_context = ExecutionContext(\n        query=query,\n        context=context_value,\n        variables=variable_values,\n        operation_name=operation_name,\n    )\n    extensions_runner = ExtensionsRunner(\n        execution_context=execution_context,\n        extensions=[extension() for extension in extensions],\n    )\n\n    additional_middlewares = additional_middlewares or []\n\n    with extensions_runner.request():\n        # Note: In graphql-core the schema would be validated here but in\n        # Strawberry we are validating it at initialisation time instead\n\n        try:\n            with extensions_runner.parsing():\n                document = parse(query)\n        except GraphQLError as error:\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        except Exception as error:  # pragma: no cover\n            error = GraphQLError(str(error), original_error=error)\n\n            return ExecutionResult(\n                data=None,\n                errors=[error],\n                extensions=extensions_runner.get_extensions_results(),\n            )\n\n        with extensions_runner.validation():\n            validation_errors = validate(schema, document)\n\n        if validation_errors:\n            return ExecutionResult(data=None, errors=validation_errors)\n\n        result = original_execute(\n            schema,\n            document,\n            root_value=root_value,\n            middleware=extensions_runner.as_middleware_manager(*additional_middlewares),\n            variable_values=variable_values,\n            operation_name=operation_name,\n            context_value=context_value,\n        )\n\n        if isawaitable(result):\n            ensure_future(cast(Awaitable[GraphQLExecutionResult], result)).cancel()\n            raise RuntimeError(\"GraphQL execution failed to complete synchronously.\")\n\n    result = cast(GraphQLExecutionResult, result)\n\n    return ExecutionResult(\n        data=result.data,\n        errors=result.errors,\n        extensions=extensions_runner.get_extensions_results(),\n    )\n", "path": "strawberry/schema/execute.py"}]}