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

Extending subscription support #467

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

sdobbelaere
Copy link
Contributor

@sdobbelaere sdobbelaere commented Jan 28, 2024

As promised on #454 I'm hereby publishing my subscription implementation for OneSila. .

What does it do:

  • Allow you to expose every model to the frontend via subscriptions.
  • Easy to extend and modify.

What it doesn't do:

  • Support query and mutation extensions
  • Follow any other internal lib safety features or restrictions.

This PR is intended as first step towards comprehensive subscriptions support for models out of the box. The reason this wasn't published sooner is because this PR should be stamped as experimental.

Types of Changes

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

Issues Fixed or Closed by This PR

Todos:

  • Investigate query/mutation extension support
  • Create one liner field declarations
  • More flexible access controle
  • Improve extendability
  • Tests
  • Add receivers import into the app.py file

Want to help?

  • Test need figuring out as this is Django-channels based.
  • ACL and extensions are an important part of query/mutations. This probably needs investigating.
  • model_subscriber() wrapper is a not a great approach towards extendability.
  • ...

@codecov-commenter
Copy link

codecov-commenter commented Jan 28, 2024

Codecov Report

Attention: 101 lines in your changes are missing coverage. Please review.

Comparison is base (b5adb23) 87.89% compared to head (0ce4729) 85.18%.

Files Patch % Lines
strawberry_django/subscriptions/publishers.py 0.00% 69 Missing ⚠️
strawberry_django/subscriptions/subscribers.py 0.00% 9 Missing ⚠️
strawberry_django/receivers.py 0.00% 8 Missing ⚠️
strawberry_django/subscriptions/receivers.py 0.00% 8 Missing ⚠️
strawberry_django/subscriptions/utils.py 0.00% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #467      +/-   ##
==========================================
- Coverage   87.89%   85.18%   -2.71%     
==========================================
  Files          37       42       +5     
  Lines        3164     3267     +103     
==========================================
+ Hits         2781     2783       +2     
- Misses        383      484     +101     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sdobbelaere sdobbelaere marked this pull request as draft January 28, 2024 13:44
Copy link
Member

@bellini666 bellini666 left a comment

Choose a reason for hiding this comment

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

I've used similar solutions in some projects, and I like the way you organized this.

Left some suggestions. Let me know if I can help you with anything here (either ping me here or on discord)

cc @patrick91 what do you think of this?

strawberry_django/apps.py Show resolved Hide resolved
strawberry_django/receivers.py Outdated Show resolved Hide resolved
strawberry_django/subscriptions/utils.py Outdated Show resolved Hide resolved
Comment on lines +7 to +12
def refresh_subscription_receiver(instance):
group = get_group(instance)
msg = get_msg(instance)

channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(group=group, message=msg)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this should be async and the caller itself should use async_to_sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll need to play with it. On that makes sense, since we're looking at async first.

Comment on lines +40 to +41
if user.is_anonymous:
raise ValidationError("Anynomous users are not allowed to subscribe.")
Copy link
Member

Choose a reason for hiding this comment

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

Hrm, why not?

I mean, which user is allowed to subscribe should be defined by the application. Maybe it is an application which allows that?

What do you think about adding a way to check for permissions using the model_subscriber function? We can even try to use the permissioning system we already have for this (it might need some adjustments)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is from the OneSila project, most endpoints are not available unless logged in. I left it here as a reminder to investigate if we can leverage the existing extensions somehow. Would prefer to stay away from a second set of permissions.

Having said that, I also still want to reshuffle a few things in order to ensure the Publisher class is easy to extend and override for custom behaviour on the Subscription class.

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.

None yet

3 participants