You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Thread Safety with SQLAlchemy Sessions and Similar Objects
73
+
74
+
The streaming portion of this package is accomplished via anyio TaskGroups. Care
75
+
needs to be taken to avoid passing objects that are not thread-safe to generators
76
+
you use to yield streaming data.
77
+
78
+
For example, if you are using SQLAlchemy, you should not use/pass an `AsyncSession`
79
+
object to your generator:
80
+
81
+
```python
82
+
# ❌ This can result in "The garbage collector is trying to clean up non-checked-in connection..." errors
83
+
asyncdefbad_route():
84
+
asyncwith AsyncSession() as session:
85
+
asyncdefgenerator():
86
+
asyncfor row in session.execute(select(User)):
87
+
yielddict(data=row)
88
+
89
+
return EventSourceResponse(generator)
90
+
```
91
+
92
+
Instead, ensure you create sessions within the generator itself
93
+
94
+
```python
95
+
# ✅ This is safe
96
+
asyncdefgood_route():
97
+
asyncdefgenerator():
98
+
asyncwith AsyncSession() as session:
99
+
asyncfor row in session.execute(select(User)):
100
+
yielddict(data=row)
101
+
102
+
return EventSourceResponse(generator)
103
+
```
104
+
72
105
## Special use cases
73
106
### Customize Ping
74
107
By default, the server sends a ping every 15 seconds. You can customize this by:
@@ -112,6 +145,26 @@ Async generators can expose tricky error and cleanup behavior especially when th
112
145
Example [`no_async_generators.py`](https://github.com/sysid/sse-starlette/pull/56#issue-1704495339) shows an alternative implementation
113
146
that does not rely on async generators but instead uses memory channels (`examples/no_async_generators.py`).
114
147
148
+
### Using pytest to test SSE Endpoints
149
+
When testing more than a single SSE endpoint via pytest, one may encounter the following error: `RuntimeError: <asyncio.locks.Event object at 0xxxx [unset]> is bound to a different event loop`.
150
+
151
+
A workaround to fix this error is to use the following fixture on all tests that use SSE:
152
+
153
+
```python
154
+
@pytest.fixture
155
+
defreset_sse_starlette_appstatus_event():
156
+
"""
157
+
Fixture that resets the appstatus event in the sse_starlette app.
158
+
159
+
Should be used on any test that uses sse_starlette to stream events.
160
+
"""
161
+
# See https://github.com/sysid/sse-starlette/issues/59
162
+
from sse_starlette.sse import AppStatus
163
+
164
+
AppStatus.should_exit_event =None
165
+
```
166
+
167
+
For details, see [Issue#59](https://github.com/sysid/sse-starlette/issues/59#issuecomment-1961678665).
0 commit comments