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

Adding the event source method to NinjaAPI and Router (SSE) #1388

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

rroblf01
Copy link

With this PR I propose to make it easier to use SSE in Django Ninja.

@rroblf01 rroblf01 changed the title Adding the event source method to NinjaAPI and Router Adding the event source method to NinjaAPI and Router (SSE) Jan 10, 2025
@vitalik
Copy link
Owner

vitalik commented Jan 11, 2025

Could you also add tests for async views ?

the sync mode does not make much sense actually as it can easily occupy all wsgi threads/processes

@rroblf01
Copy link
Author

@vitalik I need to investigate, when I test with html views it works, but when I run the tests, it fails saying

"TypeError: object StreamingHttpResponse can't be used in 'await' expression"

I will continue investigating the reason.

@rroblf01
Copy link
Author

Hello, @vitalik I have added a test to check the asynchronous endpoint.

Copy link
Contributor

@baseplate-admin baseplate-admin left a comment

Choose a reason for hiding this comment

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

One small nitpick

Comment on lines +37 to +39
@api.event_source("/path")
def event_source_operation(request):
...
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this be made async?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, it works with async

Copy link
Contributor

@baseplate-admin baseplate-admin Jan 12, 2025

Choose a reason for hiding this comment

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

My apologies, I meant can we refractor this to make it like, ( because we shouldn't allow users to lock up wsgi workers )

@api.event_source("/path")
async def event_source_operation(request):
    ...

Copy link
Author

Choose a reason for hiding this comment

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

It's possible, but Django's implementation already prevents that blocking, right?

Copy link
Author

Choose a reason for hiding this comment

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

Although a StreamingHttpResponse with an async generator will only work properly if they are using asgi instead of wsgi.
Should we still make async the default in the documentation?

Copy link
Contributor

@baseplate-admin baseplate-admin left a comment

Choose a reason for hiding this comment

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

Overall looks good, just one small change request

Comment on lines +37 to +39
@api.event_source("/path")
def event_source_operation(request):
...
Copy link
Contributor

@baseplate-admin baseplate-admin Jan 12, 2025

Choose a reason for hiding this comment

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

My apologies, I meant can we refractor this to make it like, ( because we shouldn't allow users to lock up wsgi workers )

@api.event_source("/path")
async def event_source_operation(request):
    ...

@baseplate-admin
Copy link
Contributor

Also, i have a suggestion, should we allow only async server events? Otherwise we might get complaints in the future about this sync/async approach.

@rroblf01
Copy link
Author

Also, i have a suggestion, should we allow only async server events? Otherwise we might get complaints in the future about this sync/async approach.

I understand that both should be allowed. Even the StreamingHttpResponse works better when it is synchronous (I imagine it is due to the implementation underneath)

@rroblf01
Copy link
Author

Good morning @vitalik @baseplate-admin , What changes would be good to merge this PR? Do I put in the documentation that the method is asynchronous but with a warning that it should be used with asgi when it is asynchronous?

@rroblf01
Copy link
Author

hello @vitalik @baseplate-admin How could we continue with this PR?

@baseplate-admin
Copy link
Contributor

baseplate-admin commented Jan 19, 2025

Apologies, i think @vitalik needs to give his final opinion on this PR.

Do I put in the documentation that the method is asynchronous but with a warning that it should be used with asgi when it is asynchronous?

Sounds good to me, add the comment made by vitalik, something like

Note that using synchronous SSE might block the WSGI worker, please use asynchronous SSE with ASGI worker for best performance.

add a note to HTTP operations to inform that SSE can block in WSGI
@rroblf01
Copy link
Author

I just added the notice

@baseplate-admin
Copy link
Contributor

Okay, thank you.

@vitalik will make the final call on this

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.

3 participants