Skip to content

Commit 63518fa

Browse files
committed
Make datastar opinionated about taking 0..N datastar events
1 parent 686f603 commit 63518fa

File tree

15 files changed

+206
-130
lines changed

15 files changed

+206
-130
lines changed

examples/python/django/ds/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from datetime import datetime
44

55
from datastar_py.django import (
6-
DatastarStreamingHttpResponse,
6+
DatastarResponse,
77
ServerSentEventGenerator,
88
read_signals,
99
)
@@ -65,7 +65,7 @@ async def time_updates():
6565
)
6666
await asyncio.sleep(1)
6767

68-
return DatastarStreamingHttpResponse(time_updates())
68+
return DatastarResponse(time_updates())
6969

7070

7171
# WSGI Example
@@ -121,4 +121,4 @@ def time_updates():
121121
)
122122
time.sleep(0.5)
123123

124-
return DatastarStreamingHttpResponse(time_updates())
124+
return DatastarResponse(time_updates())

examples/python/fastapi/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import uvicorn
1515
from datastar_py.fastapi import (
16-
DatastarStreamingResponse,
16+
DatastarResponse,
1717
ReadSignals,
1818
ServerSentEventGenerator,
1919
)
@@ -80,7 +80,7 @@ async def time_updates():
8080
async def updates(signals: ReadSignals):
8181
# ReadSignals is a dependency that automatically loads the signals from the request
8282
print(signals)
83-
return DatastarStreamingResponse(time_updates())
83+
return DatastarResponse(time_updates())
8484

8585

8686
if __name__ == "__main__":

examples/python/fasthtml/advanced.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from pathlib import Path
1818

1919
import polars as pl
20-
from datastar_py.fasthtml import DatastarStreamingResponse, ServerSentEventGenerator
20+
from datastar_py.fasthtml import DatastarResponse, ServerSentEventGenerator
2121
from great_tables import GT
2222
from great_tables.data import reactions
2323

@@ -94,10 +94,7 @@ def GreatTable(pattern=default_pattern):
9494
# rendered table into the DOM with the request's 'filter' value
9595
@app.post
9696
async def table(filter: str):
97-
async def _():
98-
yield ServerSentEventGenerator.merge_fragments(GreatTable(filter))
99-
100-
return DatastarStreamingResponse(_())
97+
return DatastarResponse(ServerSentEventGenerator.merge_fragments(GreatTable(filter)))
10198

10299

103100
# Define default route which returns a FastTag from a GET request.
@@ -159,7 +156,7 @@ async def clock():
159156

160157
@rt
161158
async def time():
162-
return DatastarStreamingResponse(clock())
159+
return DatastarResponse(clock())
163160

164161

165162
@rt
@@ -169,7 +166,7 @@ async def _():
169166
await asyncio.sleep(1)
170167
yield ServerSentEventGenerator.merge_fragments(HELLO_BUTTON)
171168

172-
return DatastarStreamingResponse(_())
169+
return DatastarResponse(_())
173170

174171

175172
@rt
@@ -189,7 +186,7 @@ async def _():
189186
await asyncio.sleep(1)
190187
yield ServerSentEventGenerator.merge_fragments(reset_and_hello)
191188

192-
return DatastarStreamingResponse(_())
189+
return DatastarResponse(_())
193190

194191

195192
# Define the button once so that it can be used in the index response

examples/python/fasthtml/simple.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from datetime import datetime
1313
from pathlib import Path
1414

15-
from datastar_py.fasthtml import DatastarStreamingResponse, ServerSentEventGenerator, read_signals
15+
from datastar_py.fasthtml import DatastarResponse, ServerSentEventGenerator, read_signals
1616

1717
# ruff: noqa: F403, F405
1818
from fasthtml.common import *
@@ -66,7 +66,7 @@ async def clock():
6666
async def updates(request):
6767
signals = await read_signals(request)
6868
print(signals)
69-
return DatastarStreamingResponse(clock())
69+
return DatastarResponse(clock())
7070

7171

7272
if __name__ == "__main__":

examples/python/litestar/app.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
from datetime import datetime
1313

1414
import uvicorn
15-
from datastar_py.litestar import DatastarSSE, ServerSentEventGenerator, read_signals
15+
from datastar_py.litestar import (
16+
ServerSentEventGenerator,
17+
read_signals,
18+
DatastarResponse,
19+
)
1620

1721
from litestar import Litestar, MediaType, get
1822
from litestar.di import Provide
@@ -72,9 +76,9 @@ async def time_updates() -> AsyncGenerator[str, None]:
7276
# We aren't using the signals for anything meaningful here, but `read_signals` can be
7377
# used as a dependency to automatically parse the signals from the request.
7478
@get("/updates", dependencies={"signals": Provide(read_signals)})
75-
async def updates(signals: dict | None) -> DatastarSSE:
79+
async def updates(signals: dict | None) -> DatastarResponse:
7680
print(signals)
77-
return DatastarSSE(time_updates())
81+
return DatastarResponse(time_updates())
7882

7983

8084
app = Litestar(route_handlers=[read_root, updates])

sdk/python/pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,9 @@ select = [
104104
"SIM",
105105
# isort
106106
"I",
107+
# Annotations
108+
"ANN",
109+
# Ruff specific
110+
"RUF",
107111
]
108-
fixable = ["ALL"]
112+
fixable = ["ALL"]

sdk/python/src/datastar_py/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
from .sse import SSE_HEADERS, ServerSentEventGenerator
88

9-
__all__ = ["ServerSentEventGenerator", "SSE_HEADERS"]
9+
__all__ = ["SSE_HEADERS", "ServerSentEventGenerator"]
1010

1111

1212
def _read_signals(
13-
method: str, headers: Mapping, params: Mapping, body: str | bytes
13+
method: str, headers: Mapping[str, str], params: Mapping, body: str | bytes
1414
) -> dict[str, Any] | None:
1515
if "Datastar-Request" not in headers:
1616
return None

sdk/python/src/datastar_py/django.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
11
from __future__ import annotations
22

3-
from functools import wraps
4-
from typing import Any
3+
from typing import TYPE_CHECKING, Any
4+
from warnings import deprecated
55

66
from django.http import HttpRequest
77
from django.http import StreamingHttpResponse as _StreamingHttpResponse
88

99
from . import _read_signals
10-
from .sse import SSE_HEADERS, ServerSentEventGenerator
10+
from .sse import SSE_HEADERS, DatastarEvent, DatastarEvents, ServerSentEventGenerator
11+
12+
if TYPE_CHECKING:
13+
from collections.abc import Mapping
14+
1115

1216
__all__ = [
1317
"SSE_HEADERS",
18+
"DatastarResponse",
1419
"DatastarStreamingHttpResponse",
1520
"ServerSentEventGenerator",
1621
"read_signals",
1722
]
1823

1924

20-
class DatastarStreamingHttpResponse(_StreamingHttpResponse):
21-
@wraps(_StreamingHttpResponse.__init__)
22-
def __init__(self, *args, **kwargs):
23-
kwargs["headers"] = {**SSE_HEADERS, **kwargs.get("headers", {})}
24-
super().__init__(*args, **kwargs)
25+
class DatastarResponse(_StreamingHttpResponse):
26+
"""Respond with 0..N `DatastarEvent`s"""
27+
28+
def __init__(
29+
self,
30+
content: DatastarEvents = None,
31+
*,
32+
status: int | None = None,
33+
headers: Mapping[str, str] | None = None,
34+
) -> None:
35+
if not content:
36+
super().__init__(tuple(), status=status or 204, headers=headers)
37+
return
38+
headers = {**SSE_HEADERS, **(headers or {})}
39+
if isinstance(content, DatastarEvent):
40+
content = (content,)
41+
super().__init__(content, status=status, headers=headers)
42+
43+
44+
@deprecated("Use DatastarResponse instead")
45+
class DatastarStreamingHttpResponse(DatastarResponse):
46+
pass
2547

2648

2749
def read_signals(request: HttpRequest) -> dict[str, Any] | None:

sdk/python/src/datastar_py/fastapi.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
from fastapi import Depends
44

55
from .sse import SSE_HEADERS, ServerSentEventGenerator
6-
from .starlette import DatastarStreamingResponse, read_signals
6+
from .starlette import DatastarResponse, DatastarStreamingResponse, read_signals
77

88
__all__ = [
99
"SSE_HEADERS",
10-
"ServerSentEventGenerator",
10+
"DatastarResponse",
11+
"DatastarStreamingResponse",
1112
"ReadSignals",
13+
"ServerSentEventGenerator",
1214
"read_signals",
13-
"DatastarStreamingResponse",
1415
]
1516

1617

sdk/python/src/datastar_py/fasthtml.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from .sse import SSE_HEADERS, ServerSentEventGenerator
2-
from .starlette import DatastarStreamingResponse, read_signals
2+
from .starlette import DatastarResponse, DatastarStreamingResponse, read_signals
33

44
__all__ = [
55
"SSE_HEADERS",
6+
"DatastarResponse",
67
"DatastarStreamingResponse",
78
"ServerSentEventGenerator",
89
"read_signals",

0 commit comments

Comments
 (0)