Skip to content

Commit 70b290b

Browse files
authored
Fix Starlette/FastAPI middleware for non-http scopes (#1187)
* Don't raise exceptions on non-http scopes Instead just don't process non-http scopes * CHANGELOG * Add missing return * Add a websocket test to exercise non-http scope
1 parent 4347cd6 commit 70b290b

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

CHANGELOG.asciidoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ endif::[]
3030
//===== Bug fixes
3131
//
3232
33+
=== Unreleased
34+
35+
// Unreleased changes go here
36+
// When the next release happens, nest these changes under the "Python Agent version 6.x" heading
37+
[float]
38+
===== Features
39+
40+
41+
[float]
42+
===== Bug fixes
43+
44+
* Fix handling of non-http scopes in Starlette/FastAPI middleware {pull}1187[#1187]
45+
46+
3347
[[release-notes-6.x]]
3448
=== Python Agent version 6.x
3549

elasticapm/contrib/starlette/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,10 @@ async def __call__(self, scope, receive, send):
130130
receive: receive awaitable callable
131131
send: send awaitable callable
132132
"""
133-
# we only handle the http scope, raise an exception for anything else
134-
# see https://www.uvicorn.org/#the-asgi-interface
135-
assert scope["type"] == "http"
133+
# we only handle the http scope, skip anything else.
134+
if scope["type"] != "http":
135+
await self.app(scope, receive, send)
136+
return
136137

137138
@functools.wraps(send)
138139
async def wrapped_send(message):

tests/contrib/asyncio/starlette_tests.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ async def hi_from_sub(request):
104104
async def hi_from_sub(request):
105105
return PlainTextResponse(request.path_params["name"])
106106

107+
@app.websocket_route("/ws")
108+
async def ws(websocket):
109+
await websocket.accept()
110+
await websocket.send_text("Hello, world!")
111+
await websocket.close()
112+
107113
app.add_middleware(ElasticAPM, client=elasticapm_client)
108114

109115
yield app
@@ -457,3 +463,12 @@ def test_make_client_without_config():
457463
c = make_apm_client(client_cls=TempStoreClient)
458464
c.close()
459465
assert c.config.service_name == "foo"
466+
467+
468+
def test_websocket(app, elasticapm_client):
469+
client = TestClient(app)
470+
with client.websocket_connect("/ws") as websocket:
471+
data = websocket.receive_text()
472+
assert data == "Hello, world!"
473+
474+
assert len(elasticapm_client.events[constants.TRANSACTION]) == 0

0 commit comments

Comments
 (0)