Skip to content

Python SDK: Allow implicit merge-fragments/signals events and decorator for iterator responses #809

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

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

gazpachoking
Copy link
Contributor

@gazpachoking gazpachoking commented Mar 31, 2025

I've separated this PR into two separate ideas for discussion and consideration:

  1. Allow implicit merge_fragments and merge_signals responses. This would allow you to return a string with an html fragment without wrapping it in ServerSentEventGenerator.merge_fragment Similarly a dictionary would implicitly be a merge_signals.
  2. Add a decorator that wraps a generator function in the appropriate DatastarResponse class. This would mean your route handler can be the generator function directly, rather than having to have it separate from (or contained within) the route handling function.

Putting this up as a draft for discussion before more work. Some questions to answer:

  • Do we want either of these things? I think it makes the common case of an endpoint that just merges fragments and signals super clean, but it's not that hard to do it normally, so maybe more explicit is better.
  • Naming of the decorator. sse_generator?

TODO if we like this:

  • Test django decorator
  • Do a fasthtml decorator. The starlette one would work, but it needs the special bit to turn the result from fasthtml stuff into html.
  • Update more examples? Not sure the best way to do examples, because I think we still want to show the regular method, as well as the convenience shortcuts.

@bencroker
Copy link
Collaborator

Any update on this, @gazpachoking ?

@bencroker bencroker added the sdk SDK related issues label Apr 29, 2025
@gazpachoking gazpachoking force-pushed the response-decorator branch from b3a68f0 to 9592ee9 Compare May 3, 2025 14:26
@gazpachoking
Copy link
Contributor Author

gazpachoking commented May 3, 2025

Still thinking on this. Updated it with some of the changes that have happened in the mean time. I guess there are 2 main bits to this that I'd welcome other people's opinions on:

  • A decorator that allows making your route a generator function directly, rather than having to define the generator separately than the route handler.
  • Allowing the sse iterables to just return fragments or dictionaries which automatically get interpereted as merge-fragments and merge-signals with default options without explicitly having to wrap them in ServerSentEventGenerator.merge_fragments/signals

These two pieces could be implemented separately. The second one could be made default for all frameworks without having to use any sort of decorator. Is that too much magic? The first one would use a decorator specific to each framework which would just wrap a generator function in the appropriate response class for that framework.

This shows off both ideas at once:

@app.get("/updates3")
# Wraps the resulting async generator in a DatastarStreamingResponse
@sse_generator
async def updates3():
while True:
# Implicit merge_fragments
yield f"""<span id="currentTime">{datetime.now().isoformat()}"""
await asyncio.sleep(1)
# Implicit merge_signals
yield {"currentTime": f"{datetime.now().isoformat()}"}
await asyncio.sleep(1)

@jmoppel
Copy link
Contributor

jmoppel commented May 3, 2025

My instinct on this is to wait, since the decorator is a convenience thing and not a must-have. Since we're unsure, let's build more things with Datastar and see where it goes. If we still think it is a good idea a bit down the road, we can always add this sort of thing later. There is no cost to the SDK to wait, since users still have a way to do the same thing as the decorator accomplishes.

@gazpachoking
Copy link
Contributor Author

What do you think about the implicit merge fragments and signals returns? Those could be implemented completely separate from the decorator

Allow fasthtml to use starlette decorator
@gazpachoking gazpachoking force-pushed the response-decorator branch from a62da60 to 847209b Compare May 4, 2025 00:03
@gazpachoking gazpachoking changed the title Add sse_generator decorator to reduce boilerplate for SSE responses Python SDK: Allow implicit merge-fragments/signals events and decorator for iterator responses May 4, 2025
@gazpachoking
Copy link
Contributor Author

Okay, I split the implicit merge fragments/signals away from the decorator. The implicit wrapping now works with any of the frameworks without any decorator, and we can consider the two different ideas in this PR separately. Main post updated to reflect this as well.

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

Successfully merging this pull request may close these issues.

3 participants