-
-
Notifications
You must be signed in to change notification settings - Fork 629
Change StrawberryConfig to be a dictionary instead of a class #4039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| --- | ||
| title: 0.285.0 Deprecations | ||
| slug: breaking-changes/0.285.0 | ||
| --- | ||
|
|
||
| # v0.285.0 Deprecations | ||
|
|
||
| In this release, we've simplified the schema configuration API by migrating from | ||
| a class-based approach to a dictionary-based approach. | ||
|
|
||
| ## What Changed | ||
|
|
||
| The `StrawberryConfig` class syntax is now **deprecated** and will show a | ||
| `DeprecationWarning`. The class will be removed in a future release. | ||
|
|
||
| Instead of instantiating a config class, you should now pass a plain Python | ||
| dictionary to the `config` parameter when creating a schema. | ||
|
|
||
| ## Migration | ||
|
|
||
| Convert the class instantiation to a dictionary: | ||
|
|
||
| **Before (deprecated):** | ||
|
|
||
| ```python | ||
| from strawberry.schema.config import StrawberryConfig | ||
|
|
||
| schema = strawberry.Schema( | ||
| query=Query, | ||
| config=StrawberryConfig( | ||
| auto_camel_case=True, | ||
| relay_max_results=50, | ||
| ), | ||
| ) | ||
| ``` | ||
|
|
||
| **After (recommended):** | ||
|
|
||
| ```python | ||
| schema = strawberry.Schema( | ||
| query=Query, | ||
| config={ | ||
| "auto_camel_case": True, | ||
| "relay_max_results": 50, | ||
| }, | ||
| ) | ||
| ``` | ||
|
|
||
| The old syntax will continue to work but will show this warning: | ||
|
|
||
| ``` | ||
| DeprecationWarning: Using StrawberryConfig as a class is deprecated as of v0.285.0. | ||
| Use dictionary syntax instead: config={'auto_camel_case': True}. | ||
| ``` | ||
|
|
||
| For more information, see the | ||
| [Schema Configurations](../types/schema-configurations.md) documentation. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| from .annotated_unions import ConvertUnionToAnnotatedUnion | ||
| from .config_to_dict import ConvertStrawberryConfigToDict | ||
| from .maybe_optional import ConvertMaybeToOptional | ||
| from .update_imports import UpdateImportsCodemod | ||
|
|
||
| __all__ = [ | ||
| "ConvertMaybeToOptional", | ||
| "ConvertStrawberryConfigToDict", | ||
| "ConvertUnionToAnnotatedUnion", | ||
| "UpdateImportsCodemod", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import libcst as cst | ||
| import libcst.matchers as m | ||
| from libcst.codemod import VisitorBasedCodemodCommand | ||
|
|
||
|
|
||
| class ConvertStrawberryConfigToDict(VisitorBasedCodemodCommand): | ||
| """Convert StrawberryConfig() instantiation to dict syntax. | ||
|
|
||
| This codemod converts the deprecated class-based StrawberryConfig() syntax | ||
| to the new dictionary syntax. | ||
|
|
||
| Examples: | ||
| # Before: | ||
| config = StrawberryConfig() | ||
| config = StrawberryConfig(auto_camel_case=True) | ||
|
|
||
| # After: | ||
| config = {} | ||
| config = {"auto_camel_case": True} | ||
| """ | ||
|
|
||
| DESCRIPTION: str = ( | ||
| "Converts StrawberryConfig() class instantiation to dictionary syntax" | ||
| ) | ||
|
|
||
| def leave_Call( # noqa: N802 | ||
| self, original_node: cst.Call, updated_node: cst.Call | ||
| ) -> cst.BaseExpression: | ||
| # Check if this is a StrawberryConfig() call | ||
| if not self._is_strawberry_config_call(original_node): | ||
| return updated_node | ||
|
|
||
| # If no arguments, convert to empty dict {} | ||
| if not original_node.args: | ||
| return cst.Dict([]) | ||
|
|
||
| # Convert arguments to dict entries | ||
| dict_elements = [] | ||
| for arg in original_node.args: | ||
| # Only handle keyword arguments | ||
| if arg.keyword is None: | ||
| # Positional arguments not supported, skip this conversion | ||
| return updated_node | ||
|
|
||
| # Create dict key (string literal from keyword name) | ||
| key = cst.SimpleString(f'"{arg.keyword.value}"') | ||
|
|
||
| # Create dict value (the argument value) | ||
| dict_elements.append( | ||
| cst.DictElement( | ||
| key=key, | ||
| value=arg.value, | ||
| ) | ||
| ) | ||
|
|
||
| # Return dictionary literal | ||
| return cst.Dict(elements=dict_elements) | ||
|
|
||
| def _is_strawberry_config_call(self, node: cst.Call) -> bool: | ||
| """Check if this is a call to StrawberryConfig.""" | ||
| # Check for direct StrawberryConfig() call | ||
| if m.matches(node.func, m.Name("StrawberryConfig")): | ||
| return True | ||
|
|
||
| # Check for strawberry.schema.config.StrawberryConfig() | ||
| if m.matches( | ||
| node.func, | ||
| m.Attribute( | ||
| value=m.Attribute( | ||
| value=m.Attribute( | ||
| value=m.Name("strawberry"), | ||
| attr=m.Name("schema"), | ||
| ), | ||
| attr=m.Name("config"), | ||
| ), | ||
| attr=m.Name("StrawberryConfig"), | ||
| ), | ||
| ): | ||
| return True | ||
|
|
||
| # Check for config.StrawberryConfig() | ||
| return m.matches( | ||
| node.func, | ||
| m.Attribute( | ||
| attr=m.Name("StrawberryConfig"), | ||
| ), | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,15 +88,15 @@ def _is_multipart_subscriptions( | |
| def _validate_batch_request( | ||
| self, request_data: list[GraphQLRequestData], protocol: str | ||
| ) -> None: | ||
| if self.schema.config.batching_config is None: | ||
| if self.schema.config["batching_config"] is None: | ||
| raise HTTPException(400, "Batching is not enabled") | ||
|
|
||
| if protocol == "multipart-subscription": | ||
| raise HTTPException( | ||
| 400, "Batching is not supported for multipart subscriptions" | ||
| ) | ||
|
|
||
| if len(request_data) > self.schema.config.batching_config["max_operations"]: | ||
| if len(request_data) > self.schema.config["batching_config"]["max_operations"]: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure about the visual noise we're adding here 😬
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, it's not fun 😅 |
||
| raise HTTPException(400, "Too many operations") | ||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
polish: this is not following the pattern of the ones below