Skip to content
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

Add support for extensions to the HTTP protocol #3461

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

omarzouk
Copy link

@omarzouk omarzouk commented Apr 19, 2024

Description

The GQL spec specifies a field called extensions as part of the request parameters spec in the HTTP protocol. We are missing support for this

Adding the field to be parsed and propagating it as part of the Info object. This is done by wrapping the entire context object in a temporary container, and then unwrapping it inside the Info context getter. A new function is also added to the Info class called input_extensions. It exposes the extensions data.

Example usage by the end-user:

@strawberry.field
def value_from_extensions(self, key: str, info: strawberry.Info) -> str:
    return info.input_extensions[key]

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Documentation

Issues Fixed or Closed by This PR

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

Summary by Sourcery

This pull request introduces support for the 'extensions' field in HTTP requests, allowing it to be parsed and included in the ExecutionContext. This change is accompanied by updates to the documentation and new tests to ensure proper functionality.

  • New Features:
    • Added support for the 'extensions' field in HTTP requests, allowing it to be parsed and propagated as part of the ExecutionContext.
  • Documentation:
    • Updated documentation to reflect the new support for the 'extensions' field in HTTP requests.
  • Tests:
    • Added tests to verify the correct handling and propagation of the 'extensions' field in both GET and POST HTTP requests.

@omarzouk omarzouk marked this pull request as draft April 19, 2024 17:38
@botberry
Copy link
Member

Hi, thanks for contributing to Strawberry 🍓!

We noticed that this PR is missing a RELEASE.md file. We use that to automatically do releases here on GitHub and, most importantly, to PyPI!

So as soon as this PR is merged, a release will be made 🚀.

Here's an example of RELEASE.md:

Release type: patch

Description of the changes, ideally with some examples, if adding a new feature.

Release type can be one of patch, minor or major. We use semver, so make sure to pick the appropriate type. If in doubt feel free to ask :)

Here's the tweet text:

🆕 Release (next) is out! Thanks to Omar Marzouk for the PR 👏

Get it here 👉 https://strawberry.rocks/release/(next)

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @omarzouk - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Docstrings: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.

strawberry/http/__init__.py Show resolved Hide resolved
Copy link

codecov bot commented Apr 19, 2024

Codecov Report

Attention: Patch coverage is 89.13043% with 5 lines in your changes missing coverage. Please review.

Project coverage is 94.36%. Comparing base (d502cd7) to head (ae3456b).
Report is 91 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3461      +/-   ##
==========================================
- Coverage   96.49%   94.36%   -2.13%     
==========================================
  Files         509      520      +11     
  Lines       32862    32480     -382     
  Branches     5421     3726    -1695     
==========================================
- Hits        31710    30650    -1060     
- Misses        941     1543     +602     
- Partials      211      287      +76     

Copy link

codspeed-hq bot commented Apr 19, 2024

CodSpeed Performance Report

Merging #3461 will not alter performance

Comparing omarzouk:add_http_extensions (ae3456b) with main (39ccffc)

Summary

✅ 12 untouched benchmarks

@strawberry-graphql strawberry-graphql deleted a comment from botberry Jun 22, 2024
Copy link
Member

@erikwrede erikwrede left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Can you add a test to ensure the exension dict is actually correctly passed down the chain? 🙂

Additionally, we can investigate merging the http protocol extensions with subscription extensions (need to double check if we support this already in strawberry). It might also make sense to add the protocol extensions to Info

@omarzouk
Copy link
Author

omarzouk commented Jun 24, 2024

@erikwrede Hi! yea I think I need to do a fresh take on this, I think I hit a dead end with my current approach, I've been investigating how to do it, and I think we have a couple options:

1- Wrap the context field in another object that holds the extensions and the context, i.e. wrap the field before this line, then unwrap it inside the Info class. We would then introduce an input_extensions or protocol_extensions field to Info that reads the extensions from the wrapper.

2- Extend the definition of the get_context function, add a 3rd parameter called extensions. However, this would require moving the body parsing and data fetching to happen before the get_context is called, i.e. this operation would have to move above this line. It will also require some refactoring to get a similar pattern to work with subscriptions.

The benefit of doing Option 1 would be that we can add this right away to http, without having to modify other protocols, and just include a type check for the wrapper in the info.context getter. It can then be added to other protocols over time, in other PRs.

What do u think? should I go ahead and do Option 1?

@omarzouk omarzouk requested a review from erikwrede June 24, 2024 14:16
@omarzouk
Copy link
Author

hi @erikwrede, I went ahead and implemented Option 1 mentioned above, which is to wrap the context object and unwrap it in the Info getter. I also added a new test that is passing successfully. Please let me know what you think. 🙏

@omarzouk omarzouk marked this pull request as ready for review June 24, 2024 14:24
Copy link
Contributor

sourcery-ai bot commented Jun 24, 2024

Reviewer's Guide by Sourcery

This pull request adds support for the 'extensions' field in the HTTP protocol for GraphQL requests. The changes involve parsing the 'extensions' field from the request, propagating it through the ExecutionContext, and making it accessible to applications. Additionally, tests have been added to ensure the new functionality works correctly.

File-Level Changes

Files Changes
tests/http/clients/base.py
tests/http/clients/channels.py
tests/http/clients/aiohttp.py
tests/http/clients/asgi.py
tests/http/clients/chalice.py
tests/http/clients/django.py
tests/http/clients/fastapi.py
tests/http/clients/flask.py
tests/http/clients/litestar.py
tests/http/clients/quart.py
tests/http/clients/sanic.py
tests/http/clients/starlite.py
Added 'extensions' parameter to various HTTP client request functions and updated request body construction to include 'extensions'.
strawberry/http/async_base_view.py
strawberry/http/sync_base_view.py
Wrapped context in ContextWrapper to include 'extensions' in execute_operation and parse_http_body functions.

Tips
  • Trigger a new Sourcery review by commenting @sourcery-ai review on the pull request.
  • You can change your review settings at any time by accessing your dashboard:
    • Enable or disable the Sourcery-generated pull request summary or reviewer's guide;
    • Change the review language;
  • You can always contact us if you have any questions or feedback.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @omarzouk - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 3 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 1 issue found
  • 🟡 Complexity: 2 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.

strawberry/types/info.py Show resolved Hide resolved
strawberry/http/__init__.py Show resolved Hide resolved
strawberry/types/context_wrapper.py Show resolved Hide resolved
tests/http/test_query.py Show resolved Hide resolved
strawberry/http/async_base_view.py Show resolved Hide resolved
strawberry/http/sync_base_view.py Show resolved Hide resolved
@omarzouk
Copy link
Author

pinging @patrick91 as well, since we discussed this originally in #3224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support the extensions Request Parameter for the HTTP protocol
3 participants