strawberry-graphql 0.243.1__tar.gz → 0.244.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/PKG-INFO +1 -1
  2. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/pyproject.toml +1 -1
  3. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/aiohttp/views.py +58 -44
  4. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/asgi/__init__.py +62 -61
  5. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/__init__.py +1 -6
  6. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/handlers/base.py +2 -2
  7. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/handlers/http_handler.py +18 -1
  8. strawberry_graphql-0.244.1/strawberry/channels/handlers/ws_handler.py +187 -0
  9. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/query_codegen.py +8 -6
  10. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/views.py +19 -1
  11. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/fastapi/router.py +27 -45
  12. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/flask/views.py +15 -1
  13. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/async_base_view.py +136 -16
  14. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/exceptions.py +4 -0
  15. strawberry_graphql-0.244.1/strawberry/http/typevars.py +20 -0
  16. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/litestar/controller.py +77 -86
  17. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/quart/views.py +15 -1
  18. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/sanic/views.py +21 -1
  19. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +41 -40
  20. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_ws/handlers.py +46 -45
  21. strawberry_graphql-0.243.1/strawberry/aiohttp/handlers/__init__.py +0 -6
  22. strawberry_graphql-0.243.1/strawberry/aiohttp/handlers/graphql_transport_ws_handler.py +0 -62
  23. strawberry_graphql-0.243.1/strawberry/aiohttp/handlers/graphql_ws_handler.py +0 -69
  24. strawberry_graphql-0.243.1/strawberry/asgi/handlers/__init__.py +0 -6
  25. strawberry_graphql-0.243.1/strawberry/asgi/handlers/graphql_transport_ws_handler.py +0 -66
  26. strawberry_graphql-0.243.1/strawberry/asgi/handlers/graphql_ws_handler.py +0 -71
  27. strawberry_graphql-0.243.1/strawberry/channels/handlers/graphql_transport_ws_handler.py +0 -62
  28. strawberry_graphql-0.243.1/strawberry/channels/handlers/graphql_ws_handler.py +0 -72
  29. strawberry_graphql-0.243.1/strawberry/channels/handlers/ws_handler.py +0 -132
  30. strawberry_graphql-0.243.1/strawberry/fastapi/handlers/__init__.py +0 -6
  31. strawberry_graphql-0.243.1/strawberry/fastapi/handlers/graphql_transport_ws_handler.py +0 -20
  32. strawberry_graphql-0.243.1/strawberry/fastapi/handlers/graphql_ws_handler.py +0 -18
  33. strawberry_graphql-0.243.1/strawberry/http/typevars.py +0 -10
  34. strawberry_graphql-0.243.1/strawberry/litestar/handlers/graphql_transport_ws_handler.py +0 -60
  35. strawberry_graphql-0.243.1/strawberry/litestar/handlers/graphql_ws_handler.py +0 -66
  36. strawberry_graphql-0.243.1/strawberry/types/fields/__init__.py +0 -0
  37. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/LICENSE +0 -0
  38. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/README.md +0 -0
  39. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/__init__.py +0 -0
  40. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/__main__.py +0 -0
  41. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/aiohttp/__init__.py +0 -0
  42. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/aiohttp/test/__init__.py +0 -0
  43. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/aiohttp/test/client.py +0 -0
  44. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/annotation.py +0 -0
  45. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/asgi/test/__init__.py +0 -0
  46. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/asgi/test/client.py +0 -0
  47. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/chalice/__init__.py +0 -0
  48. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/chalice/views.py +0 -0
  49. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/handlers/__init__.py +0 -0
  50. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/router.py +0 -0
  51. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/channels/testing.py +0 -0
  52. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/__init__.py +0 -0
  53. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/app.py +0 -0
  54. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/__init__.py +0 -0
  55. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/codegen.py +0 -0
  56. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/export_schema.py +0 -0
  57. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/schema_codegen.py +0 -0
  58. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/server.py +0 -0
  59. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/upgrade/__init__.py +0 -0
  60. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/upgrade/_fake_progress.py +0 -0
  61. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/commands/upgrade/_run_codemod.py +0 -0
  62. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/constants.py +0 -0
  63. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/debug_server.py +0 -0
  64. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/utils/__init__.py +0 -0
  65. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/cli/utils/load_schema.py +0 -0
  66. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/__init__.py +0 -0
  67. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/exceptions.py +0 -0
  68. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/plugins/__init__.py +0 -0
  69. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/plugins/print_operation.py +0 -0
  70. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/plugins/python.py +0 -0
  71. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/plugins/typescript.py +0 -0
  72. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codegen/types.py +0 -0
  73. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codemods/__init__.py +0 -0
  74. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codemods/annotated_unions.py +0 -0
  75. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/codemods/update_imports.py +0 -0
  76. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/dataloader.py +0 -0
  77. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/directive.py +0 -0
  78. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/__init__.py +0 -0
  79. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/apps.py +0 -0
  80. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/context.py +0 -0
  81. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/test/__init__.py +0 -0
  82. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/django/test/client.py +0 -0
  83. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/__init__.py +0 -0
  84. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/conflicting_arguments.py +0 -0
  85. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/duplicated_type_name.py +0 -0
  86. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/exception.py +0 -0
  87. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/exception_source.py +0 -0
  88. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/handler.py +0 -0
  89. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/invalid_argument_type.py +0 -0
  90. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/invalid_union_type.py +0 -0
  91. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/missing_arguments_annotations.py +0 -0
  92. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/missing_dependencies.py +0 -0
  93. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/missing_field_annotation.py +0 -0
  94. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/missing_return_annotation.py +0 -0
  95. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/not_a_strawberry_enum.py +0 -0
  96. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/object_is_not_a_class.py +0 -0
  97. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/object_is_not_an_enum.py +0 -0
  98. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/permission_fail_silently_requires_optional.py +0 -0
  99. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/private_strawberry_field.py +0 -0
  100. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/scalar_already_registered.py +0 -0
  101. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/syntax.py +0 -0
  102. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/unresolved_field_type.py +0 -0
  103. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/utils/__init__.py +0 -0
  104. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/exceptions/utils/source_finder.py +0 -0
  105. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/__init__.py +0 -0
  106. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/__init__.py +0 -0
  107. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/_compat.py +0 -0
  108. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/conversion.py +0 -0
  109. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/conversion_types.py +0 -0
  110. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/error_type.py +0 -0
  111. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/exceptions.py +0 -0
  112. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/fields.py +0 -0
  113. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/object_type.py +0 -0
  114. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/experimental/pydantic/utils.py +0 -0
  115. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/LICENSE +0 -0
  116. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/__init__.py +0 -0
  117. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/dataclasses/LICENSE +0 -0
  118. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/dataclasses/__init__.py +0 -0
  119. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/dataclasses/dataclasses.py +0 -0
  120. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/ext/mypy_plugin.py +0 -0
  121. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/__init__.py +0 -0
  122. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/add_validation_rules.py +0 -0
  123. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/base_extension.py +0 -0
  124. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/context.py +0 -0
  125. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/directives.py +0 -0
  126. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/disable_validation.py +0 -0
  127. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/field_extension.py +0 -0
  128. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/mask_errors.py +0 -0
  129. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/max_aliases.py +0 -0
  130. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/max_tokens.py +0 -0
  131. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/parser_cache.py +0 -0
  132. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/pyinstrument.py +0 -0
  133. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/query_depth_limiter.py +0 -0
  134. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/runner.py +0 -0
  135. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/__init__.py +0 -0
  136. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/apollo.py +0 -0
  137. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/datadog.py +0 -0
  138. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/opentelemetry.py +0 -0
  139. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/sentry.py +0 -0
  140. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/tracing/utils.py +0 -0
  141. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/utils.py +0 -0
  142. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/extensions/validation_cache.py +0 -0
  143. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/fastapi/__init__.py +0 -0
  144. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/fastapi/context.py +0 -0
  145. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/__init__.py +0 -0
  146. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/argument.py +0 -0
  147. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/enum.py +0 -0
  148. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/field.py +0 -0
  149. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/mutation.py +0 -0
  150. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/object_type.py +0 -0
  151. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/scalar.py +0 -0
  152. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/schema.py +0 -0
  153. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/schema_directive.py +0 -0
  154. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/schema_directives.py +0 -0
  155. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/types.py +0 -0
  156. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/federation/union.py +0 -0
  157. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/field_extensions/__init__.py +0 -0
  158. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/field_extensions/input_mutation.py +0 -0
  159. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/file_uploads/__init__.py +0 -0
  160. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/file_uploads/scalars.py +0 -0
  161. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/file_uploads/utils.py +0 -0
  162. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/flask/__init__.py +0 -0
  163. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/__init__.py +0 -0
  164. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/base.py +0 -0
  165. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/ides.py +0 -0
  166. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/parse_content_type.py +0 -0
  167. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/sync_base_view.py +0 -0
  168. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/temporal_response.py +0 -0
  169. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/http/types.py +0 -0
  170. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/litestar/__init__.py +0 -0
  171. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/parent.py +0 -0
  172. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/permission.py +0 -0
  173. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/printer/__init__.py +0 -0
  174. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/printer/ast_from_value.py +0 -0
  175. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/printer/printer.py +0 -0
  176. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/py.typed +0 -0
  177. {strawberry_graphql-0.243.1/strawberry/litestar/handlers → strawberry_graphql-0.244.1/strawberry/quart}/__init__.py +0 -0
  178. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/relay/__init__.py +0 -0
  179. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/relay/exceptions.py +0 -0
  180. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/relay/fields.py +0 -0
  181. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/relay/types.py +0 -0
  182. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/relay/utils.py +0 -0
  183. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/resolvers.py +0 -0
  184. {strawberry_graphql-0.243.1/strawberry/quart → strawberry_graphql-0.244.1/strawberry/sanic}/__init__.py +0 -0
  185. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/sanic/context.py +0 -0
  186. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/sanic/utils.py +0 -0
  187. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/scalars.py +0 -0
  188. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/__init__.py +0 -0
  189. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/base.py +0 -0
  190. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/compat.py +0 -0
  191. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/config.py +0 -0
  192. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/exceptions.py +0 -0
  193. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/execute.py +0 -0
  194. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/name_converter.py +0 -0
  195. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/schema.py +0 -0
  196. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/schema_converter.py +0 -0
  197. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/subscribe.py +0 -0
  198. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/types/__init__.py +0 -0
  199. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/types/base_scalars.py +0 -0
  200. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/types/concrete_type.py +0 -0
  201. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/types/scalar.py +0 -0
  202. {strawberry_graphql-0.243.1/strawberry/sanic → strawberry_graphql-0.244.1/strawberry/schema/validation_rules}/__init__.py +0 -0
  203. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema/validation_rules/one_of.py +0 -0
  204. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema_codegen/__init__.py +0 -0
  205. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema_directive.py +0 -0
  206. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/schema_directives.py +0 -0
  207. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/static/apollo-sandbox.html +0 -0
  208. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/static/graphiql.html +0 -0
  209. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/static/pathfinder.html +0 -0
  210. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/__init__.py +0 -0
  211. {strawberry_graphql-0.243.1/strawberry/schema/validation_rules → strawberry_graphql-0.244.1/strawberry/subscriptions/protocols}/__init__.py +0 -0
  212. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py +0 -0
  213. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_transport_ws/types.py +0 -0
  214. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_ws/__init__.py +0 -0
  215. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/subscriptions/protocols/graphql_ws/types.py +0 -0
  216. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/test/__init__.py +0 -0
  217. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/test/client.py +0 -0
  218. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/tools/__init__.py +0 -0
  219. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/tools/create_type.py +0 -0
  220. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/tools/merge_types.py +0 -0
  221. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/__init__.py +0 -0
  222. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/arguments.py +0 -0
  223. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/auto.py +0 -0
  224. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/base.py +0 -0
  225. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/enum.py +0 -0
  226. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/execution.py +0 -0
  227. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/field.py +0 -0
  228. {strawberry_graphql-0.243.1/strawberry/subscriptions/protocols → strawberry_graphql-0.244.1/strawberry/types/fields}/__init__.py +0 -0
  229. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/fields/resolver.py +0 -0
  230. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/graphql.py +0 -0
  231. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/info.py +0 -0
  232. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/lazy_type.py +0 -0
  233. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/mutation.py +0 -0
  234. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/nodes.py +0 -0
  235. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/object_type.py +0 -0
  236. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/private.py +0 -0
  237. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/scalar.py +0 -0
  238. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/type_resolver.py +0 -0
  239. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/union.py +0 -0
  240. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/types/unset.py +0 -0
  241. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/__init__.py +0 -0
  242. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/aio.py +0 -0
  243. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/await_maybe.py +0 -0
  244. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/dataclasses.py +0 -0
  245. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/debug.py +0 -0
  246. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/deprecations.py +0 -0
  247. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/graphql_lexer.py +0 -0
  248. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/importer.py +0 -0
  249. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/inspect.py +0 -0
  250. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/logging.py +0 -0
  251. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/operation.py +0 -0
  252. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/str_converters.py +0 -0
  253. {strawberry_graphql-0.243.1 → strawberry_graphql-0.244.1}/strawberry/utils/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.243.1
3
+ Version: 0.244.1
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "strawberry-graphql"
3
3
  packages = [ { include = "strawberry" } ]
4
- version = "0.243.1"
4
+ version = "0.244.1"
5
5
  description = "A library for creating GraphQL APIs"
6
6
  authors = ["Patrick Arminio <patrick.arminio@gmail.com>"]
7
7
  license = "MIT"
@@ -4,6 +4,7 @@ import asyncio
4
4
  import warnings
5
5
  from datetime import timedelta
6
6
  from io import BytesIO
7
+ from json.decoder import JSONDecodeError
7
8
  from typing import (
8
9
  TYPE_CHECKING,
9
10
  Any,
@@ -16,15 +17,16 @@ from typing import (
16
17
  Union,
17
18
  cast,
18
19
  )
20
+ from typing_extensions import TypeGuard
19
21
 
20
- from aiohttp import web
22
+ from aiohttp import http, web
21
23
  from aiohttp.multipart import BodyPartReader
22
- from strawberry.aiohttp.handlers import (
23
- GraphQLTransportWSHandler,
24
- GraphQLWSHandler,
24
+ from strawberry.http.async_base_view import (
25
+ AsyncBaseHTTPView,
26
+ AsyncHTTPRequestAdapter,
27
+ AsyncWebSocketAdapter,
25
28
  )
26
- from strawberry.http.async_base_view import AsyncBaseHTTPView, AsyncHTTPRequestAdapter
27
- from strawberry.http.exceptions import HTTPException
29
+ from strawberry.http.exceptions import HTTPException, NonJsonMessageReceived
28
30
  from strawberry.http.types import FormData, HTTPMethod, QueryParams
29
31
  from strawberry.http.typevars import (
30
32
  Context,
@@ -79,11 +81,36 @@ class AioHTTPRequestAdapter(AsyncHTTPRequestAdapter):
79
81
  return self.headers.get("content-type")
80
82
 
81
83
 
84
+ class AioHTTPWebSocketAdapter(AsyncWebSocketAdapter):
85
+ def __init__(self, request: web.Request, ws: web.WebSocketResponse) -> None:
86
+ self.request = request
87
+ self.ws = ws
88
+
89
+ async def iter_json(self) -> AsyncGenerator[Dict[str, object], None]:
90
+ async for ws_message in self.ws:
91
+ if ws_message.type == http.WSMsgType.TEXT:
92
+ try:
93
+ yield ws_message.json()
94
+ except JSONDecodeError:
95
+ raise NonJsonMessageReceived()
96
+
97
+ elif ws_message.type == http.WSMsgType.BINARY:
98
+ raise NonJsonMessageReceived()
99
+
100
+ async def send_json(self, message: Mapping[str, object]) -> None:
101
+ await self.ws.send_json(message)
102
+
103
+ async def close(self, code: int, reason: str) -> None:
104
+ await self.ws.close(code=code, message=reason.encode())
105
+
106
+
82
107
  class GraphQLView(
83
108
  AsyncBaseHTTPView[
84
109
  web.Request,
85
110
  Union[web.Response, web.StreamResponse],
86
111
  web.Response,
112
+ web.Request,
113
+ web.WebSocketResponse,
87
114
  Context,
88
115
  RootValue,
89
116
  ]
@@ -92,10 +119,9 @@ class GraphQLView(
92
119
  # bare handler function.
93
120
  _is_coroutine = asyncio.coroutines._is_coroutine # type: ignore[attr-defined]
94
121
 
95
- graphql_transport_ws_handler_class = GraphQLTransportWSHandler
96
- graphql_ws_handler_class = GraphQLWSHandler
97
122
  allow_queries_via_get = True
98
123
  request_adapter_class = AioHTTPRequestAdapter
124
+ websocket_adapter_class = AioHTTPWebSocketAdapter
99
125
 
100
126
  def __init__(
101
127
  self,
@@ -138,48 +164,36 @@ class GraphQLView(
138
164
  async def get_sub_response(self, request: web.Request) -> web.Response:
139
165
  return web.Response()
140
166
 
141
- async def __call__(self, request: web.Request) -> web.StreamResponse:
167
+ def is_websocket_request(self, request: web.Request) -> TypeGuard[web.Request]:
142
168
  ws = web.WebSocketResponse(protocols=self.subscription_protocols)
143
- ws_test = ws.can_prepare(request)
144
-
145
- if not ws_test.ok:
146
- try:
147
- return await self.run(request=request)
148
- except HTTPException as e:
149
- return web.Response(
150
- body=e.reason,
151
- status=e.status_code,
152
- )
153
-
154
- if ws_test.protocol == GRAPHQL_TRANSPORT_WS_PROTOCOL:
155
- return await self.graphql_transport_ws_handler_class(
156
- schema=self.schema,
157
- debug=self.debug,
158
- connection_init_wait_timeout=self.connection_init_wait_timeout,
159
- get_context=self.get_context, # type: ignore
160
- get_root_value=self.get_root_value,
161
- request=request,
162
- ).handle()
163
- elif ws_test.protocol == GRAPHQL_WS_PROTOCOL:
164
- return await self.graphql_ws_handler_class(
165
- schema=self.schema,
166
- debug=self.debug,
167
- keep_alive=self.keep_alive,
168
- keep_alive_interval=self.keep_alive_interval,
169
- get_context=self.get_context,
170
- get_root_value=self.get_root_value,
171
- request=request,
172
- ).handle()
173
- else:
174
- await ws.prepare(request)
175
- await ws.close(code=4406, message=b"Subprotocol not acceptable")
176
- return ws
169
+ return ws.can_prepare(request).ok
170
+
171
+ async def pick_websocket_subprotocol(self, request: web.Request) -> Optional[str]:
172
+ ws = web.WebSocketResponse(protocols=self.subscription_protocols)
173
+ return ws.can_prepare(request).protocol
174
+
175
+ async def create_websocket_response(
176
+ self, request: web.Request, subprotocol: Optional[str]
177
+ ) -> web.WebSocketResponse:
178
+ protocols = [subprotocol] if subprotocol else []
179
+ ws = web.WebSocketResponse(protocols=protocols)
180
+ await ws.prepare(request)
181
+ return ws
182
+
183
+ async def __call__(self, request: web.Request) -> web.StreamResponse:
184
+ try:
185
+ return await self.run(request=request)
186
+ except HTTPException as e:
187
+ return web.Response(
188
+ body=e.reason,
189
+ status=e.status_code,
190
+ )
177
191
 
178
192
  async def get_root_value(self, request: web.Request) -> Optional[RootValue]:
179
193
  return None
180
194
 
181
195
  async def get_context(
182
- self, request: web.Request, response: web.Response
196
+ self, request: web.Request, response: Union[web.Response, web.WebSocketResponse]
183
197
  ) -> Context:
184
198
  return {"request": request, "response": response} # type: ignore
185
199
 
@@ -2,9 +2,11 @@ from __future__ import annotations
2
2
 
3
3
  import warnings
4
4
  from datetime import timedelta
5
+ from json import JSONDecodeError
5
6
  from typing import (
6
7
  TYPE_CHECKING,
7
8
  Any,
9
+ AsyncGenerator,
8
10
  AsyncIterator,
9
11
  Callable,
10
12
  Dict,
@@ -14,6 +16,7 @@ from typing import (
14
16
  Union,
15
17
  cast,
16
18
  )
19
+ from typing_extensions import TypeGuard
17
20
 
18
21
  from starlette import status
19
22
  from starlette.requests import Request
@@ -23,14 +26,14 @@ from starlette.responses import (
23
26
  Response,
24
27
  StreamingResponse,
25
28
  )
26
- from starlette.websockets import WebSocket
29
+ from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
27
30
 
28
- from strawberry.asgi.handlers import (
29
- GraphQLTransportWSHandler,
30
- GraphQLWSHandler,
31
+ from strawberry.http.async_base_view import (
32
+ AsyncBaseHTTPView,
33
+ AsyncHTTPRequestAdapter,
34
+ AsyncWebSocketAdapter,
31
35
  )
32
- from strawberry.http.async_base_view import AsyncBaseHTTPView, AsyncHTTPRequestAdapter
33
- from strawberry.http.exceptions import HTTPException
36
+ from strawberry.http.exceptions import HTTPException, NonJsonMessageReceived
34
37
  from strawberry.http.types import FormData, HTTPMethod, QueryParams
35
38
  from strawberry.http.typevars import (
36
39
  Context,
@@ -78,19 +81,41 @@ class ASGIRequestAdapter(AsyncHTTPRequestAdapter):
78
81
  )
79
82
 
80
83
 
84
+ class ASGIWebSocketAdapter(AsyncWebSocketAdapter):
85
+ def __init__(self, request: WebSocket, response: WebSocket) -> None:
86
+ self.ws = response
87
+
88
+ async def iter_json(self) -> AsyncGenerator[Dict[str, object], None]:
89
+ try:
90
+ try:
91
+ while self.ws.application_state != WebSocketState.DISCONNECTED:
92
+ yield await self.ws.receive_json()
93
+ except (KeyError, JSONDecodeError):
94
+ raise NonJsonMessageReceived()
95
+ except WebSocketDisconnect: # pragma: no cover
96
+ pass
97
+
98
+ async def send_json(self, message: Mapping[str, object]) -> None:
99
+ await self.ws.send_json(message)
100
+
101
+ async def close(self, code: int, reason: str) -> None:
102
+ await self.ws.close(code=code, reason=reason)
103
+
104
+
81
105
  class GraphQL(
82
106
  AsyncBaseHTTPView[
83
- Union[Request, WebSocket],
107
+ Request,
84
108
  Response,
85
109
  Response,
110
+ WebSocket,
111
+ WebSocket,
86
112
  Context,
87
113
  RootValue,
88
114
  ]
89
115
  ):
90
- graphql_transport_ws_handler_class = GraphQLTransportWSHandler
91
- graphql_ws_handler_class = GraphQLWSHandler
92
116
  allow_queries_via_get = True
93
- request_adapter_class = ASGIRequestAdapter # pyright: ignore
117
+ request_adapter_class = ASGIRequestAdapter
118
+ websocket_adapter_class = ASGIWebSocketAdapter
94
119
 
95
120
  def __init__(
96
121
  self,
@@ -129,51 +154,25 @@ class GraphQL(
129
154
 
130
155
  async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
131
156
  if scope["type"] == "http":
132
- return await self.handle_http(scope, receive, send)
157
+ http_request = Request(scope=scope, receive=receive)
133
158
 
134
- elif scope["type"] == "websocket":
135
- ws = WebSocket(scope, receive=receive, send=send)
136
- preferred_protocol = self.pick_preferred_protocol(ws)
137
-
138
- if preferred_protocol == GRAPHQL_TRANSPORT_WS_PROTOCOL:
139
- await self.graphql_transport_ws_handler_class(
140
- schema=self.schema,
141
- debug=self.debug,
142
- connection_init_wait_timeout=self.connection_init_wait_timeout,
143
- get_context=self.get_context,
144
- get_root_value=self.get_root_value,
145
- ws=ws,
146
- ).handle()
147
-
148
- elif preferred_protocol == GRAPHQL_WS_PROTOCOL:
149
- await self.graphql_ws_handler_class(
150
- schema=self.schema,
151
- debug=self.debug,
152
- keep_alive=self.keep_alive,
153
- keep_alive_interval=self.keep_alive_interval,
154
- get_context=self.get_context,
155
- get_root_value=self.get_root_value,
156
- ws=ws,
157
- ).handle()
158
-
159
- else:
160
- # Subprotocol not acceptable
161
- await ws.close(code=4406)
159
+ try:
160
+ response = await self.run(http_request)
161
+ except HTTPException as e:
162
+ response = PlainTextResponse(e.reason, status_code=e.status_code)
162
163
 
164
+ await response(scope, receive, send)
165
+ elif scope["type"] == "websocket":
166
+ ws_request = WebSocket(scope, receive=receive, send=send)
167
+ await self.run(ws_request)
163
168
  else: # pragma: no cover
164
169
  raise ValueError("Unknown scope type: {!r}".format(scope["type"]))
165
170
 
166
- def pick_preferred_protocol(self, ws: WebSocket) -> Optional[str]:
167
- protocols = ws["subprotocols"]
168
- intersection = set(protocols) & set(self.protocols)
169
- sorted_intersection = sorted(intersection, key=protocols.index)
170
- return next(iter(sorted_intersection), None)
171
-
172
171
  async def get_root_value(self, request: Union[Request, WebSocket]) -> Optional[Any]:
173
172
  return None
174
173
 
175
174
  async def get_context(
176
- self, request: Union[Request, WebSocket], response: Response
175
+ self, request: Union[Request, WebSocket], response: Union[Response, WebSocket]
177
176
  ) -> Context:
178
177
  return {"request": request, "response": response} # type: ignore
179
178
 
@@ -187,21 +186,6 @@ class GraphQL(
187
186
 
188
187
  return sub_response
189
188
 
190
- async def handle_http(
191
- self,
192
- scope: Scope,
193
- receive: Receive,
194
- send: Send,
195
- ) -> None:
196
- request = Request(scope=scope, receive=receive)
197
-
198
- try:
199
- response = await self.run(request)
200
- except HTTPException as e:
201
- response = PlainTextResponse(e.reason, status_code=e.status_code) # pyright: ignore
202
-
203
- await response(scope, receive, send)
204
-
205
189
  async def render_graphql_ide(self, request: Union[Request, WebSocket]) -> Response:
206
190
  return HTMLResponse(self.graphql_ide_html)
207
191
 
@@ -239,3 +223,20 @@ class GraphQL(
239
223
  **headers,
240
224
  },
241
225
  )
226
+
227
+ def is_websocket_request(
228
+ self, request: Union[Request, WebSocket]
229
+ ) -> TypeGuard[WebSocket]:
230
+ return request.scope["type"] == "websocket"
231
+
232
+ async def pick_websocket_subprotocol(self, request: WebSocket) -> Optional[str]:
233
+ protocols = request["subprotocols"]
234
+ intersection = set(protocols) & set(self.protocols)
235
+ sorted_intersection = sorted(intersection, key=protocols.index)
236
+ return next(iter(sorted_intersection), None)
237
+
238
+ async def create_websocket_response(
239
+ self, request: WebSocket, subprotocol: Optional[str]
240
+ ) -> WebSocket:
241
+ await request.accept(subprotocol=subprotocol)
242
+ return request
@@ -1,6 +1,4 @@
1
- from .handlers.base import ChannelsConsumer, ChannelsWSConsumer
2
- from .handlers.graphql_transport_ws_handler import GraphQLTransportWSHandler
3
- from .handlers.graphql_ws_handler import GraphQLWSHandler
1
+ from .handlers.base import ChannelsConsumer
4
2
  from .handlers.http_handler import (
5
3
  ChannelsRequest,
6
4
  GraphQLHTTPConsumer,
@@ -12,10 +10,7 @@ from .router import GraphQLProtocolTypeRouter
12
10
  __all__ = [
13
11
  "ChannelsConsumer",
14
12
  "ChannelsRequest",
15
- "ChannelsWSConsumer",
16
13
  "GraphQLProtocolTypeRouter",
17
- "GraphQLWSHandler",
18
- "GraphQLTransportWSHandler",
19
14
  "GraphQLHTTPConsumer",
20
15
  "GraphQLWSConsumer",
21
16
  "SyncGraphQLHTTPConsumer",
@@ -16,7 +16,7 @@ from typing_extensions import Literal, Protocol, TypedDict
16
16
  from weakref import WeakSet
17
17
 
18
18
  from channels.consumer import AsyncConsumer
19
- from channels.generic.websocket import AsyncJsonWebsocketConsumer
19
+ from channels.generic.websocket import AsyncWebsocketConsumer
20
20
 
21
21
 
22
22
  class ChannelsMessage(TypedDict, total=False):
@@ -210,7 +210,7 @@ class ChannelsConsumer(AsyncConsumer):
210
210
  return
211
211
 
212
212
 
213
- class ChannelsWSConsumer(ChannelsConsumer, AsyncJsonWebsocketConsumer):
213
+ class ChannelsWSConsumer(ChannelsConsumer, AsyncWebsocketConsumer):
214
214
  """Base channels websocket async consumer."""
215
215
 
216
216
 
@@ -15,7 +15,7 @@ from typing import (
15
15
  Optional,
16
16
  Union,
17
17
  )
18
- from typing_extensions import assert_never
18
+ from typing_extensions import TypeGuard, assert_never
19
19
  from urllib.parse import parse_qs
20
20
 
21
21
  from django.conf import settings
@@ -233,6 +233,8 @@ class GraphQLHTTPConsumer(
233
233
  ChannelsRequest,
234
234
  Union[ChannelsResponse, MultipartChannelsResponse],
235
235
  TemporalResponse,
236
+ ChannelsRequest,
237
+ TemporalResponse,
236
238
  Context,
237
239
  RootValue,
238
240
  ],
@@ -298,6 +300,21 @@ class GraphQLHTTPConsumer(
298
300
  content=self.graphql_ide_html.encode(), content_type="text/html"
299
301
  )
300
302
 
303
+ def is_websocket_request(
304
+ self, request: ChannelsRequest
305
+ ) -> TypeGuard[ChannelsRequest]:
306
+ return False
307
+
308
+ async def pick_websocket_subprotocol(
309
+ self, request: ChannelsRequest
310
+ ) -> Optional[str]:
311
+ return None
312
+
313
+ async def create_websocket_response(
314
+ self, request: ChannelsRequest, subprotocol: Optional[str]
315
+ ) -> TemporalResponse:
316
+ raise NotImplementedError
317
+
301
318
 
302
319
  class SyncGraphQLHTTPConsumer(
303
320
  BaseGraphQLHTTPConsumer,
@@ -0,0 +1,187 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import datetime
5
+ import json
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ AsyncGenerator,
9
+ Dict,
10
+ Mapping,
11
+ Optional,
12
+ Tuple,
13
+ TypedDict,
14
+ Union,
15
+ )
16
+ from typing_extensions import TypeGuard
17
+
18
+ from strawberry.http.async_base_view import AsyncBaseHTTPView, AsyncWebSocketAdapter
19
+ from strawberry.http.exceptions import NonJsonMessageReceived
20
+ from strawberry.http.typevars import Context, RootValue
21
+ from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
22
+
23
+ from .base import ChannelsWSConsumer
24
+
25
+ if TYPE_CHECKING:
26
+ from strawberry.http import GraphQLHTTPResponse
27
+ from strawberry.schema import BaseSchema
28
+
29
+
30
+ class ChannelsWebSocketAdapter(AsyncWebSocketAdapter):
31
+ def __init__(self, request: GraphQLWSConsumer, response: GraphQLWSConsumer) -> None:
32
+ self.ws_consumer = response
33
+
34
+ async def iter_json(self) -> AsyncGenerator[Dict[str, object], None]:
35
+ while True:
36
+ message = await self.ws_consumer.message_queue.get()
37
+
38
+ if message["disconnected"]:
39
+ break
40
+
41
+ if message["message"] is None:
42
+ raise NonJsonMessageReceived()
43
+
44
+ try:
45
+ yield json.loads(message["message"])
46
+ except json.JSONDecodeError:
47
+ raise NonJsonMessageReceived()
48
+
49
+ async def send_json(self, message: Mapping[str, object]) -> None:
50
+ serialized_message = json.dumps(message)
51
+ await self.ws_consumer.send(serialized_message)
52
+
53
+ async def close(self, code: int, reason: str) -> None:
54
+ await self.ws_consumer.close(code=code, reason=reason)
55
+
56
+
57
+ class MessageQueueData(TypedDict):
58
+ message: Union[str, None]
59
+ disconnected: bool
60
+
61
+
62
+ class GraphQLWSConsumer(
63
+ ChannelsWSConsumer,
64
+ AsyncBaseHTTPView[
65
+ "GraphQLWSConsumer",
66
+ "GraphQLWSConsumer",
67
+ "GraphQLWSConsumer",
68
+ "GraphQLWSConsumer",
69
+ "GraphQLWSConsumer",
70
+ Context,
71
+ RootValue,
72
+ ],
73
+ ):
74
+ """A channels websocket consumer for GraphQL.
75
+
76
+ This handles the connections, then hands off to the appropriate
77
+ handler based on the subprotocol.
78
+
79
+ To use this, place it in your ProtocolTypeRouter for your channels project, e.g:
80
+
81
+ ```
82
+ from strawberry.channels import GraphQLHttpRouter
83
+ from channels.routing import ProtocolTypeRouter
84
+ from django.core.asgi import get_asgi_application
85
+
86
+ application = ProtocolTypeRouter({
87
+ "http": URLRouter([
88
+ re_path("^graphql", GraphQLHTTPRouter(schema=schema)),
89
+ re_path("^", get_asgi_application()),
90
+ ]),
91
+ "websocket": URLRouter([
92
+ re_path("^ws/graphql", GraphQLWebSocketRouter(schema=schema)),
93
+ ]),
94
+ })
95
+ ```
96
+ """
97
+
98
+ websocket_adapter_class = ChannelsWebSocketAdapter
99
+
100
+ def __init__(
101
+ self,
102
+ schema: BaseSchema,
103
+ keep_alive: bool = False,
104
+ keep_alive_interval: float = 1,
105
+ debug: bool = False,
106
+ subscription_protocols: Tuple[str, str] = (
107
+ GRAPHQL_TRANSPORT_WS_PROTOCOL,
108
+ GRAPHQL_WS_PROTOCOL,
109
+ ),
110
+ connection_init_wait_timeout: Optional[datetime.timedelta] = None,
111
+ ) -> None:
112
+ if connection_init_wait_timeout is None:
113
+ connection_init_wait_timeout = datetime.timedelta(minutes=1)
114
+ self.connection_init_wait_timeout = connection_init_wait_timeout
115
+ self.schema = schema
116
+ self.keep_alive = keep_alive
117
+ self.keep_alive_interval = keep_alive_interval
118
+ self.debug = debug
119
+ self.protocols = subscription_protocols
120
+ self.message_queue: asyncio.Queue[MessageQueueData] = asyncio.Queue()
121
+ self.run_task: Optional[asyncio.Task] = None
122
+
123
+ super().__init__()
124
+
125
+ async def connect(self) -> None:
126
+ self.run_task = asyncio.create_task(self.run(self))
127
+
128
+ async def receive(
129
+ self, text_data: Optional[str] = None, bytes_data: Optional[bytes] = None
130
+ ) -> None:
131
+ if text_data:
132
+ self.message_queue.put_nowait({"message": text_data, "disconnected": False})
133
+ else:
134
+ self.message_queue.put_nowait({"message": None, "disconnected": False})
135
+
136
+ async def disconnect(self, code: int) -> None:
137
+ self.message_queue.put_nowait({"message": None, "disconnected": True})
138
+ assert self.run_task
139
+ await self.run_task
140
+
141
+ async def get_root_value(self, request: GraphQLWSConsumer) -> Optional[RootValue]:
142
+ return None
143
+
144
+ async def get_context(
145
+ self, request: GraphQLWSConsumer, response: GraphQLWSConsumer
146
+ ) -> Context:
147
+ return {
148
+ "request": request,
149
+ "ws": request,
150
+ } # type: ignore
151
+
152
+ @property
153
+ def allow_queries_via_get(self) -> bool:
154
+ return False
155
+
156
+ async def get_sub_response(self, request: GraphQLWSConsumer) -> GraphQLWSConsumer:
157
+ raise NotImplementedError
158
+
159
+ def create_response(
160
+ self, response_data: GraphQLHTTPResponse, sub_response: GraphQLWSConsumer
161
+ ) -> GraphQLWSConsumer:
162
+ raise NotImplementedError
163
+
164
+ async def render_graphql_ide(self, request: GraphQLWSConsumer) -> GraphQLWSConsumer:
165
+ raise NotImplementedError
166
+
167
+ def is_websocket_request(
168
+ self, request: GraphQLWSConsumer
169
+ ) -> TypeGuard[GraphQLWSConsumer]:
170
+ return True
171
+
172
+ async def pick_websocket_subprotocol(
173
+ self, request: GraphQLWSConsumer
174
+ ) -> Optional[str]:
175
+ protocols = request.scope["subprotocols"]
176
+ intersection = set(protocols) & set(self.protocols)
177
+ sorted_intersection = sorted(intersection, key=protocols.index)
178
+ return next(iter(sorted_intersection), None)
179
+
180
+ async def create_websocket_response(
181
+ self, request: GraphQLWSConsumer, subprotocol: Optional[str]
182
+ ) -> GraphQLWSConsumer:
183
+ await request.accept(subprotocol=subprotocol)
184
+ return request
185
+
186
+
187
+ __all__ = ["GraphQLWSConsumer"]
@@ -645,20 +645,22 @@ class QueryCodegen:
645
645
  ) -> Tuple[
646
646
  Union[type, StrawberryType], Optional[Callable[[GraphQLType], GraphQLType]]
647
647
  ]:
648
- wrapper = None
648
+ wrapper: Optional[Callable[[GraphQLType], GraphQLType]] = None
649
649
 
650
650
  if isinstance(type_, StrawberryOptional):
651
- type_, wrapper = self._unwrap_type(type_.of_type)
651
+ type_, previous_wrapper = self._unwrap_type(type_.of_type)
652
652
  wrapper = (
653
653
  GraphQLOptional
654
- if wrapper is None
655
- else lambda t: GraphQLOptional(wrapper(t)) # type: ignore[misc]
654
+ if previous_wrapper is None
655
+ else lambda t: GraphQLOptional(previous_wrapper(t)) # type: ignore[misc]
656
656
  )
657
657
 
658
658
  elif isinstance(type_, StrawberryList):
659
- type_, wrapper = self._unwrap_type(type_.of_type)
659
+ type_, previous_wrapper = self._unwrap_type(type_.of_type)
660
660
  wrapper = (
661
- GraphQLList if wrapper is None else lambda t: GraphQLList(wrapper(t))
661
+ GraphQLList
662
+ if previous_wrapper is None
663
+ else lambda t: GraphQLList(previous_wrapper(t))
662
664
  )
663
665
 
664
666
  elif isinstance(type_, LazyType):