Skip to content
This repository was archived by the owner on Jun 13, 2023. It is now read-only.

Commit 475c87c

Browse files
authored
fix(fastapi): custom responses
1 parent 65be6d3 commit 475c87c

3 files changed

Lines changed: 36 additions & 30 deletions

File tree

epsagon/events/dbapi.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,14 @@ def __init__(
7272

7373
# in case of pg instrumentation we extract data from the dsn property
7474
if hasattr(connection, 'dsn'):
75-
print_debug('Parsing using dsn')
7675
dsn = parse_dsn(connection.dsn)
77-
print_debug('Parsed dsn: {}'.format(dsn))
7876
db_name = dsn.get('dbname', '')
7977
host = dsn.get('host', 'local')
8078
query = cursor.query
8179
else:
8280
query = _args[0]
8381
host = connection.extract_hostname
8482
db_name = connection.extract_dbname
85-
print_debug(
86-
'Extracted db name - {}, host - {}, query - {}'.format(
87-
db_name, host, query
88-
)
89-
)
9083

9184
self.resource['name'] = db_name if db_name else host
9285

@@ -104,11 +97,6 @@ def __init__(
10497
host,
10598
self.RESOURCE_TYPE
10699
)
107-
print_debug(
108-
'{}: resource name - {}, operation - {}'.format(
109-
self.event_id, self.resource['name'], self.resource['operation']
110-
)
111-
)
112100
self.resource['metadata'] = {
113101
'Host': host,
114102
'Driver': connection.__class__.__module__.split('.')[0],
@@ -121,11 +109,6 @@ def __init__(
121109
(not trace_factory.metadata_only)
122110
):
123111
self.resource['metadata']['Query'] = query[:MAX_QUERY_SIZE]
124-
print_debug(
125-
'{}: collected query {}'.format(
126-
self.event_id, self.resource['metadata']['Query']
127-
)
128-
)
129112

130113
if exception is None:
131114
# Update response data
@@ -174,7 +157,6 @@ def create_event(wrapped, cursor_wrapper, args, kwargs, start_time,
174157
:param exception:
175158
:return:
176159
"""
177-
print_debug('Creating DBAPI event')
178160
event = DBAPIEvent(
179161
cursor_wrapper.connection_wrapper,
180162
cursor_wrapper,
@@ -183,5 +165,4 @@ def create_event(wrapped, cursor_wrapper, args, kwargs, start_time,
183165
start_time,
184166
exception,
185167
)
186-
print_debug('Adding DBAPI event to trace')
187168
trace_factory.add_event(event)

epsagon/runners/fastapi.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import uuid
88
import warnings
99
from fastapi.responses import (
10+
Response,
1011
JSONResponse,
1112
HTMLResponse,
1213
PlainTextResponse,
@@ -107,16 +108,16 @@ def update_response(self, response):
107108
'Response Data',
108109
body
109110
)
111+
if isinstance(response, Response):
112+
response_headers = dict(response.headers.items())
113+
if response.headers:
114+
add_data_if_needed(
115+
self.resource['metadata'],
116+
'Response Headers',
117+
response_headers
118+
)
110119

111-
response_headers = dict(response.headers.items())
112-
if response.headers:
113-
add_data_if_needed(
114-
self.resource['metadata'],
115-
'Response Headers',
116-
response_headers
117-
)
118-
119-
self.resource['metadata']['status_code'] = response.status_code
120+
self.resource['metadata']['status_code'] = response.status_code
120121

121-
if response.status_code >= 500:
122-
self.set_error()
122+
if response.status_code >= 500:
123+
self.set_error()

tests/wrappers/test_fastapi_wrapper.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import pytest
66
import asynctest
77
import asyncio
8+
from typing import List
89
from httpx import AsyncClient
910
from fastapi import FastAPI, APIRouter, Request
1011
from fastapi.responses import JSONResponse
@@ -22,6 +23,8 @@
2223
MULTIPLE_THREADS_ROUTE = f'/{MULTIPLE_THREADS_KEY}'
2324
MULTIPLE_THREADS_RETURN_VALUE = MULTIPLE_THREADS_KEY
2425
TEST_POST_DATA = {'post_test': '123'}
26+
CUSTOM_RESPONSE = ["A"]
27+
CUSTOM_RESPONSE_PATH = "/custom_response"
2528

2629
def _get_response_data(key):
2730
return {key: key}
@@ -33,6 +36,9 @@ def _get_response(key):
3336
def handle():
3437
return _get_response(RETURN_VALUE)
3538

39+
def handle_custom_response(response_model=List[str]):
40+
return CUSTOM_RESPONSE
41+
3642
def handle_given_request(request: Request):
3743
assert request.method == 'POST'
3844
loop = None
@@ -70,6 +76,7 @@ def handle_error():
7076
def fastapi_app():
7177
app = FastAPI()
7278
app.add_api_route("/", handle, methods=["GET"])
79+
app.add_api_route(CUSTOM_RESPONSE_PATH, handle_custom_response, methods=["GET"])
7380
app.add_api_route(REQUEST_OBJ_PATH, handle_given_request, methods=["POST"])
7481
app.add_api_route("/a", handle_a, methods=["GET"])
7582
app.add_api_route("/b", handle_b, methods=["GET"])
@@ -100,6 +107,23 @@ async def test_fastapi_sanity(trace_transport, fastapi_app):
100107
assert not trace_factory.traces
101108

102109

110+
@pytest.mark.asyncio
111+
async def test_fastapi_custom_response(trace_transport, fastapi_app):
112+
"""Sanity test."""
113+
request_path = f'{CUSTOM_RESPONSE_PATH}?x=testval'
114+
async with AsyncClient(app=fastapi_app, base_url="http://test") as ac:
115+
response = await ac.get(request_path)
116+
response_data = response.json()
117+
runner = trace_transport.last_trace.events[0]
118+
assert isinstance(runner, FastapiRunner)
119+
assert runner.resource['name'].startswith('127.0.0.1')
120+
assert runner.resource['metadata']['Path'] == CUSTOM_RESPONSE_PATH
121+
assert runner.resource['metadata']['Query Params'] == { 'x': 'testval'}
122+
assert response_data == CUSTOM_RESPONSE
123+
# validating no `zombie` traces exist
124+
assert not trace_factory.traces
125+
126+
103127
@pytest.mark.asyncio
104128
async def test_fastapi_given_request(trace_transport, fastapi_app):
105129
"""Sanity test."""

0 commit comments

Comments
 (0)